<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Association;
use App\Services\DomainVerificationService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class DomainController extends Controller
{
    public function __construct(
        protected DomainVerificationService $domainService
    ) {}

    /**
     * Get domain configuration for an association
     */
    public function show(Request $request, Association $association): JsonResponse
    {
        // Authorize: user must be member of this association
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        return response()->json([
            'domain_type' => $association->domain_type,
            'subdomain' => $association->subdomain,
            'custom_domain' => $association->custom_domain,
            'domain_verified_at' => $association->domain_verified_at,
            'primary_url' => $association->primary_url,
            'all_urls' => $association->getAllUrls(),
            'can_use_subdomain' => $association->canUseSubdomain(),
            'can_use_custom_domain' => $association->canUseCustomDomain(),
            'verification_instructions' => $association->custom_domain && !$association->domain_verified_at
                ? $association->getCustomDomainDnsInstructions()
                : null,
        ]);
    }

    /**
     * Configure subdomain for an association
     */
    public function configureSubdomain(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // Check if plan allows subdomain
        if (!$association->canUseSubdomain()) {
            return response()->json([
                'message' => 'Your current subscription plan does not include subdomain support. Please upgrade to Professional or Enterprise plan.',
            ], 403);
        }

        // Validate
        $validator = Validator::make($request->all(), [
            'subdomain' => 'required|string|min:3|max:63|regex:/^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])?$/',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $validator->errors(),
            ], 422);
        }

        // Configure subdomain
        $result = $this->domainService->configureSubdomain($association, $request->subdomain);

        return response()->json($result, $result['success'] ? 200 : 400);
    }

    /**
     * Add and verify custom domain for an association
     */
    public function addCustomDomain(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // Check if plan allows custom domain
        if (!$association->canUseCustomDomain()) {
            return response()->json([
                'message' => 'Your current subscription plan does not include custom domain support. Please upgrade to Enterprise plan.',
            ], 403);
        }

        // Validate
        $validator = Validator::make($request->all(), [
            'domain' => 'required|string|max:255',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'message' => 'Validation failed',
                'errors' => $validator->errors(),
            ], 422);
        }

        // Clean domain (remove protocol, www, trailing slash)
        $domain = preg_replace('#^https?://#', '', $request->domain);
        $domain = preg_replace('#^www\.#', '', $domain);
        $domain = rtrim($domain, '/');

        // Verify domain
        $result = $this->domainService->verifyCustomDomain($association, $domain);

        return response()->json($result, $result['success'] ? 200 : 400);
    }

    /**
     * Request verification token for custom domain
     */
    public function getVerificationToken(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        // Generate or retrieve token
        $token = $association->domain_verification_token
            ?? $association->generateDomainVerificationToken();

        return response()->json([
            'verification_token' => $token,
            'txt_record' => $association->getDomainVerificationTxtRecord(),
            'instructions' => $association->getCustomDomainDnsInstructions(),
        ]);
    }

    /**
     * Retry domain verification
     */
    public function retryVerification(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        if (!$association->custom_domain) {
            return response()->json(['message' => 'No custom domain configured'], 400);
        }

        // Re-verify
        $result = $this->domainService->verifyCustomDomain($association, $association->custom_domain);

        return response()->json($result, $result['success'] ? 200 : 400);
    }

    /**
     * Remove custom domain
     */
    public function removeCustomDomain(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $result = $this->domainService->removeCustomDomain($association);

        return response()->json($result);
    }

    /**
     * Remove subdomain
     */
    public function removeSubdomain(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $result = $this->domainService->removeSubdomain($association);

        return response()->json($result);
    }

    /**
     * Switch back to path-based URL
     */
    public function switchToPathBased(Request $request, Association $association): JsonResponse
    {
        // Authorize
        if (!$request->user()->associations->contains($association)) {
            return response()->json(['message' => 'Unauthorized'], 403);
        }

        $association->update(['domain_type' => 'path']);

        return response()->json([
            'success' => true,
            'message' => 'Switched to path-based URL successfully',
            'primary_url' => $association->primary_url,
        ]);
    }
}
