<?php

namespace App\Http\Controllers\WebAdmin;

use App\Http\Controllers\Controller;
use App\Models\Domain;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

/**
 * A company's own "Custom domain" screen — add the domain they already
 * own, get DNS instructions, verify it, and from then on it serves their
 * account exactly like their handed-out subdomain does. Nothing here
 * touches another company's domains: Domain's BelongsToCompany scope
 * enforces that on every query below, route-model binding included.
 */
class DomainController extends Controller
{
    public function index(): View
    {
        $domains = Domain::orderByDesc('is_primary')->orderBy('hostname')->get();

        return view('setting.domains', compact('domains'));
    }

    public function store(Request $request): RedirectResponse
    {
        $company = currentCompany();
        abort_unless($company, 403);

        $validated = $request->validate([
            'hostname' => [
                'required', 'string', 'max:255',
                'regex:/^(?!-)[a-z0-9-]{1,63}(?<!-)(\.[a-z0-9-]{1,63})+$/i',
                'unique:domains,hostname',
            ],
        ]);

        $hostname = strtolower($validated['hostname']);
        $root = tenantRootDomain();

        if ($hostname === $root || str_ends_with($hostname, '.' . $root)) {
            return back()
                ->withErrors(['hostname' => __("That's part of our own domain — a custom domain needs to be one you already own.")])
                ->withInput();
        }

        Domain::create([
            'company_id' => $company->id,
            'hostname' => $hostname,
            'type' => 'custom',
            'verification_token' => Domain::generateVerificationToken(),
            'ssl_status' => 'pending',
            'is_primary' => false,
        ]);

        return back()->with('success', __('Domain added — follow the instructions below to verify it.'));
    }

    public function verify(Domain $domain): RedirectResponse
    {
        if ($domain->isVerified()) {
            return back()->with('success', __(':hostname is already verified.', ['hostname' => $domain->hostname]));
        }

        $records = @dns_get_record('_abic-verify.' . $domain->hostname, DNS_TXT) ?: [];
        $found = collect($records)->contains(fn($record) => ($record['txt'] ?? null) === $domain->verification_token);

        if (!$found) {
            return back()->with(
                'error',
                __("We couldn't find that TXT record yet. DNS changes can take a few minutes to a few hours to reach us — try again shortly.")
            );
        }

        $domain->verified_at = now();
        $domain->ssl_status = 'pending';
        $domain->save();

        return back()->with(
            'success',
            __(':hostname is verified — a certificate is issued automatically the next time someone visits it.', ['hostname' => $domain->hostname])
        );
    }

    public function delete(Domain $domain): RedirectResponse
    {
        if ($domain->is_primary) {
            return back()->with('error', __("Your handed-out subdomain can't be removed."));
        }

        $domain->delete();

        return back()->with('success', __('Domain removed.'));
    }
}
