<?php

declare(strict_types=1);

namespace App\Http\Controllers\Public;

use App\Domain\Domain\Models\Domain;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Str;

class AutoconfigController extends Controller
{
    /**
     * Thunderbird / Mozilla autoconfig endpoint.
     * Thunderbird checks: GET https://autoconfig.<domain>/mail/config-v1.1.xml
     * or GET https://<panel>/mail/config-v1.1.xml?emailaddress=user@example.com
     */
    public function thunderbird(Request $request): Response
    {
        $domain = $this->resolveDomain($request);

        if (! $domain) {
            abort(404, 'Domain bulunamadı.');
        }

        $mailHost = config('mail.server_hostname', 'mail.'.$domain);

        $xml = view('autoconfig.thunderbird', [
            'domain' => $domain,
            'mail_host' => $mailHost,
        ])->render();

        return response($xml, 200)
            ->header('Content-Type', 'application/xml; charset=UTF-8')
            ->header('Cache-Control', 'public, max-age=3600');
    }

    /**
     * Microsoft Autodiscover endpoint.
     * Outlook POSTs XML to: POST https://autodiscover.<domain>/autodiscover/autodiscover.xml
     * Case variants are also registered in routes.
     */
    public function autodiscover(Request $request): Response
    {
        $xmlBody = $request->getContent();

        preg_match('/<EMailAddress>(.*?)<\/EMailAddress>/i', $xmlBody, $m);
        $email = $m[1] ?? $request->get('email');
        $domain = $email ? Str::after($email, '@') : null;

        // Fallback: derive from Host header (autodiscover.example.com → example.com)
        if (! $domain) {
            $host = $request->getHost();
            $domain = Str::startsWith($host, 'autodiscover.') ? Str::after($host, 'autodiscover.') : null;
        }

        if (! $domain) {
            abort(400, 'E-posta adresi belirlenemedi.');
        }

        $domainModel = Domain::where('name', $domain)->first();
        if (! $domainModel) {
            abort(404, 'Domain kayıtlı değil.');
        }

        $mailHost = config('mail.server_hostname', 'mail.'.$domain);

        $xml = view('autoconfig.autodiscover', [
            'email' => $email ?? 'user@'.$domain,
            'domain' => $domain,
            'mail_host' => $mailHost,
        ])->render();

        return response($xml, 200)
            ->header('Content-Type', 'application/xml; charset=UTF-8');
    }

    /**
     * Apple Mail .mobileconfig profile.
     * GET https://<panel>/mail/apple.mobileconfig?email=user@example.com
     */
    public function applemail(Request $request): Response
    {
        $email = $request->get('email', '');
        $domain = $email ? Str::after($email, '@') : null;

        // Fallback: derive domain from Host header
        if (! $domain) {
            $host = $request->getHost();
            $domain = Str::startsWith($host, 'autoconfig.') ? Str::after($host, 'autoconfig.') : $host;
        }

        $domainModel = Domain::where('name', $domain)->first();
        if (! $domainModel) {
            abort(404, 'Domain kayıtlı değil.');
        }

        $mailHost = config('mail.server_hostname', 'mail.'.$domain);

        $xml = view('autoconfig.mobileconfig', [
            'email' => $email ?: ('mail@'.$domain),
            'domain' => $domain,
            'mail_host' => $mailHost,
            'profile_uuid' => strtoupper(str_replace('-', '', md5('onox-mail-'.$domain))),
            'imap_uuid' => strtoupper(str_replace('-', '', md5('imap-'.$domain))),
            'smtp_uuid' => strtoupper(str_replace('-', '', md5('smtp-'.$domain))),
        ])->render();

        return response($xml, 200)
            ->header('Content-Type', 'application/x-apple-aspen-config; charset=UTF-8')
            ->header('Content-Disposition', 'attachment; filename="onox-mail.mobileconfig"');
    }

    // ── Helpers ─────────────────────────────────────────────────────────────

    private function resolveDomain(Request $request): ?string
    {
        // 1. ?emailaddress=user@example.com query param (Thunderbird standard)
        if ($request->has('emailaddress')) {
            return Str::after($request->get('emailaddress'), '@') ?: null;
        }

        // 2. Host header autoconfig.example.com → example.com
        $host = $request->getHost();
        if (Str::startsWith($host, 'autoconfig.')) {
            $candidate = Str::after($host, 'autoconfig.');
            if (Domain::where('name', $candidate)->exists()) {
                return $candidate;
            }
        }

        return null;
    }
}
