<?php

namespace App\Http\Controllers\Store;

use App\Http\Controllers\Controller;
use App\Models\Brand;
use App\Models\ClientActivityLog;
use App\Models\ProductGroup;
use App\Models\Reseller;
use App\Models\Tld;
use App\Services\CommissionCalculationService;
use App\Services\DomainVerificationService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class ResellerSiteController extends Controller
{
    public function __construct(
        private DomainVerificationService $domainService,
        private CommissionCalculationService $commissionService,
    ) {}

    public function index()
    {
        $reseller = $this->getReseller();

        $sites = Brand::where('reseller_id', $reseller->id)
            ->withCount('clients')
            ->orderByDesc('created_at')
            ->get();

        // Attach DNS status to each site
        $sites->each(function ($site) {
            $site->dns_status = $this->domainService->getStatus($site);
        });

        return view('clientarea.reseller.sites.index', compact('reseller', 'sites'));
    }

    public function create()
    {
        $reseller = $this->getReseller();
        $productGroups = $this->allowedProductGroups($reseller);
        $tlds = $this->allowedTlds($reseller);

        return view('clientarea.reseller.sites.create', compact('reseller', 'productGroups', 'tlds'));
    }

    public function store(Request $request)
    {
        $reseller = $this->getReseller();

        $request->validate([
            'name' => 'required|string|max:255',
            'domain' => 'nullable|string|max:255|unique:brands,domain',
            'logo' => 'nullable|string|max:500',
            'favicon' => 'nullable|string|max:500',
            'primary_color' => 'nullable|string|max:20',
            'secondary_color' => 'nullable|string|max:20',
            'custom_css' => 'nullable|string',
            'custom_js' => 'nullable|string',
            'footer_text' => 'nullable|string',
            'contact_email' => 'nullable|email|max:255',
            'contact_phone' => 'nullable|string|max:50',
            'visible_product_groups' => 'nullable|array',
            'visible_tlds' => 'nullable|array',
        ]);

        // PRC-841 — vitrin ⊆ admin izin havuzu (form kurcalansa bile)
        $this->assertWithinAllowedPool($reseller, $request);

        DB::beginTransaction();

        try {
            $brand = Brand::create([
                'name' => $request->name,
                'slug' => Str::slug($request->name),
                'domain' => $request->domain ?: null,
                'reseller_id' => $reseller->id,
                'logo' => $request->logo,
                'favicon' => $request->favicon,
                'primary_color' => $request->primary_color,
                'secondary_color' => $request->secondary_color,
                'custom_css' => $request->custom_css,
                'custom_js' => $request->custom_js,
                'footer_text' => $request->footer_text,
                'contact_email' => $request->contact_email,
                'contact_phone' => $request->contact_phone,
                'visible_product_groups' => $request->visible_product_groups,
                'visible_tlds' => $request->visible_tlds,
                'domain_verification_token' => $request->domain ? $this->domainService->generateToken() : null,
                'is_active' => true,
            ]);

            ClientActivityLog::log(
                action: 'reseller',
                description: "Created site: {$brand->name}" . ($brand->domain ? " ({$brand->domain})" : '')
            );

            DB::commit();

            return redirect()->route('store.auth.reseller.sites.index')
                ->with('success', 'Site created successfully.');
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function edit(Brand $site)
    {
        $reseller = $this->getReseller();

        if ($site->reseller_id !== $reseller->id) {
            abort(403);
        }

        $productGroups = $this->allowedProductGroups($reseller);
        $tlds = $this->allowedTlds($reseller);
        $dnsStatus = $this->domainService->getStatus($site);
        // PRC-840 — SSL sağlık göstergesi (yalnız domain aktifken kontrol edilir)
        $sslOk = $dnsStatus === 'active' ? $this->domainService->checkSsl($site) : null;

        return view('clientarea.reseller.sites.edit', compact('reseller', 'site', 'productGroups', 'tlds', 'dnsStatus', 'sslOk'));
    }

    public function update(Request $request, Brand $site)
    {
        $reseller = $this->getReseller();

        if ($site->reseller_id !== $reseller->id) {
            abort(403);
        }

        $request->validate([
            'name' => 'required|string|max:255',
            'domain' => 'nullable|string|max:255|unique:brands,domain,' . $site->id,
            'logo' => 'nullable|string|max:500',
            'favicon' => 'nullable|string|max:500',
            'primary_color' => 'nullable|string|max:20',
            'secondary_color' => 'nullable|string|max:20',
            'custom_css' => 'nullable|string',
            'custom_js' => 'nullable|string',
            'footer_text' => 'nullable|string',
            'contact_email' => 'nullable|email|max:255',
            'contact_phone' => 'nullable|string|max:50',
            'visible_product_groups' => 'nullable|array',
            'visible_tlds' => 'nullable|array',
        ]);

        // PRC-841 — vitrin ⊆ admin izin havuzu (form kurcalansa bile)
        $this->assertWithinAllowedPool($reseller, $request);

        DB::beginTransaction();

        try {
            $domainChanged = $site->domain !== $request->domain;

            $site->update([
                'name' => $request->name,
                'domain' => $request->domain ?: null,
                'logo' => $request->logo,
                'favicon' => $request->favicon,
                'primary_color' => $request->primary_color,
                'secondary_color' => $request->secondary_color,
                'custom_css' => $request->custom_css,
                'custom_js' => $request->custom_js,
                'footer_text' => $request->footer_text,
                'contact_email' => $request->contact_email,
                'contact_phone' => $request->contact_phone,
                'visible_product_groups' => $request->visible_product_groups,
                'visible_tlds' => $request->visible_tlds,
            ]);

            // Reset verification if domain changed
            if ($domainChanged && $request->domain) {
                $site->update([
                    'domain_verification_token' => $this->domainService->generateToken(),
                    'domain_verified' => false,
                    'domain_verified_at' => null,
                ]);
            }

            DB::commit();

            return redirect()->route('store.auth.reseller.sites.edit', $site)
                ->with('success', 'Site updated successfully.');
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function verifyDomain(Brand $site)
    {
        $reseller = $this->getReseller();

        if ($site->reseller_id !== $reseller->id) {
            abort(403);
        }

        if ($this->domainService->verifyTxtRecord($site)) {
            return back()->with('success', 'Domain verified successfully!');
        }

        return back()->with('error', 'Domain verification failed. Please check your TXT record and try again.');
    }

    public function pricing()
    {
        $reseller = $this->getReseller();

        if (! $reseller->group_id) {
            return view('clientarea.reseller.pricing', [
                'reseller' => $reseller,
                'pricingTable' => [],
            ]);
        }

        $group = $reseller->group;
        $pricingTable = $this->commissionService->getPricingTable($group);

        return view('clientarea.reseller.pricing', compact('reseller', 'group', 'pricingTable'));
    }

    private function getReseller(): Reseller
    {
        $client = Auth::guard('client')->user();
        $reseller = $client->resellerProfile;

        if (! $reseller || $reseller->status !== 'active') {
            abort(403);
        }

        return $reseller;
    }

    /**
     * PRC-841 — reseller'ın seçebileceği ürün grupları (admin izin havuzu;
     * null = tümü). Form seçenekleri de bu listeden gelir.
     */
    private function allowedProductGroups(Reseller $reseller)
    {
        return ProductGroup::where('is_active', true)
            ->when(
                is_array($reseller->allowed_product_groups) && $reseller->allowed_product_groups !== [],
                fn ($q) => $q->whereIn('id', array_map('intval', $reseller->allowed_product_groups))
            )
            ->orderBy('name')->get();
    }

    /** PRC-841 — reseller'ın seçebileceği TLD'ler (admin izin havuzu; null = tümü). */
    private function allowedTlds(Reseller $reseller)
    {
        $allowed = $reseller->allowed_tlds;
        $normalized = (is_array($allowed) && $allowed !== [])
            ? array_map(fn ($t) => '.' . ltrim((string) $t, '.'), $allowed)
            : null;

        return Tld::where('status', 'active')
            ->when($normalized !== null, fn ($q) => $q->whereIn('tld', $normalized))
            ->orderBy('tld')->get();
    }

    /**
     * PRC-841 — gönderilen vitrin seçimi admin izin havuzunun alt kümesi olmalı
     * (checkbox listesi zaten kısıtlı ama form kurcalamaya karşı sunucu guard'ı).
     * Runtime'da BrandContext ayrıca kesişim uygular (savunma derinliği).
     */
    private function assertWithinAllowedPool(Reseller $reseller, Request $request): void
    {
        $allowedGroups = is_array($reseller->allowed_product_groups) && $reseller->allowed_product_groups !== []
            ? array_map('intval', $reseller->allowed_product_groups)
            : null;
        if ($allowedGroups !== null) {
            $picked = array_map('intval', $request->input('visible_product_groups', []) ?? []);
            if (array_diff($picked, $allowedGroups) !== []) {
                abort(422, 'Seçilen ürün grupları izinli havuzun dışında.');
            }
        }

        $allowedTlds = is_array($reseller->allowed_tlds) && $reseller->allowed_tlds !== []
            ? array_map(fn ($t) => '.' . ltrim((string) $t, '.'), $reseller->allowed_tlds)
            : null;
        if ($allowedTlds !== null) {
            $picked = array_map(fn ($t) => '.' . ltrim((string) $t, '.'), $request->input('visible_tlds', []) ?? []);
            if (array_diff($picked, $allowedTlds) !== []) {
                abort(422, 'Seçilen TLD listesi izinli havuzun dışında.');
            }
        }
    }
}
