<?php

namespace App\Support\DealerBranding;

use App\Models\Dealer;
use App\Support\Color\AutoContrast;
use Illuminate\Support\Facades\Storage;

final class DealerBrandingResolver
{
    /**
     * Returns resolved branding tokens + computed CSS vars for the "current dealer".
     *
     * Resolution order per field:
     * 1) explicit dealer DB value
     * 2) dealer preset (theme_preset_key)
     * 3) default preset: mtt
     */
    public function resolve(?Dealer $explicitDealer = null): array
    {
        $dealer = $explicitDealer ?: $this->currentDealer();

        // Fallbacks reflect the current MTT shell exactly (Tailwind defaults).
        $nav = $dealer?->nav_color ?: '#262626'; // neutral-800
        $accent = $dealer?->accent_color ?: '#dc2626'; // red-600
        $accent2 = $dealer?->accent_color_2 ?: $nav;
        $bg = $dealer?->background_color ?: '#f3f4f6'; // gray-100
        $topbar = $dealer?->topbar_color ?: '#ffffff'; // current top bar is white

        // Preserve CURRENT MTT shell text appearance:
        // - nav uses text-gray-200 (#e5e7eb), not pure white
        $navText = AutoContrast::readableTextColor($nav, lightText: '#e5e7eb', darkText: '#111827');
        $accentText = AutoContrast::readableTextColor($accent, lightText: '#ffffff', darkText: '#111827');
        $accent2Text = AutoContrast::readableTextColor($accent2, lightText: '#ffffff', darkText: '#111827');
        // Top bar defaults must match the original MTT look:
        // - title: text-gray-900 (#111827) on white
        // - subtitle: text-gray-500 (#6b7280) on white
        // and auto-flip to readable light text on dark top bars.
        $topbarIsDark = AutoContrast::isDark($topbar);
        $topbarTitleText = $topbarIsDark ? '#ffffff' : '#111827';
        $topbarSubtitleText = $topbarIsDark ? '#d1d5db' : '#6b7280'; // gray-300 / gray-500

        // Mobile user button currently uses neutral-700 (#404040) independent of dealer;
        // keep that as the default muted accent.
        $accent2Muted = $accent2;

        $accentRing = AutoContrast::rgba($accent, 0.6) ?? 'rgba(239, 68, 68, 0.6)';
        $accentDivider = AutoContrast::rgba($accent, 0.8) ?? 'rgba(220, 38, 38, 0.8)';
        $accentHover = $this->darkenColor($accent, 0.12) ?? '#b91c1c'; // close to red-700 by default

        $logoPath = $this->pick($dealer?->logo_path, null, 'images/mega-theron-logo.png');
        $faviconPath = $this->pick($dealer?->favicon_path, null, null);

        return [
            'dealer' => $dealer,
            'tokens' => [
                'logo_path' => $logoPath,
                'favicon_path' => $faviconPath,
                'nav_color' => $nav,
                'accent_color' => $accent,
                'accent_color_2' => $accent2,
                'background_color' => $bg,
                'topbar_color' => $topbar,
            ],
            'css_vars' => [
                '--dealer-nav-color' => $nav,
                '--dealer-nav-text-color' => $navText,
                '--dealer-accent-color' => $accent,
                '--dealer-accent-text-color' => $accentText,
                '--dealer-accent-2-color' => $accent2,
                '--dealer-accent-2-text-color' => $accent2Text,
                '--dealer-accent-2-muted-color' => $accent2Muted,
                '--dealer-background-color' => $bg,
                '--dealer-topbar-color' => $topbar,
                '--dealer-topbar-text-color' => $topbarTitleText,
                '--dealer-topbar-subtext-color' => $topbarSubtitleText,

                // Extra vars to preserve existing MTT details exactly.
                '--dealer-accent-ring-color' => $accentRing,
                '--dealer-accent-divider-color' => $accentDivider,
                '--dealer-accent-hover-color' => $accentHover,
            ],
            'assets' => [
                'logo_url' => $this->resolveLogoUrl($dealer),
                'favicon_url' => $this->resolveFaviconUrl($dealer),
            ],
        ];
    }

    /**
     * Darken a hex color by mixing it with black.
     *
     * @param string $hex    A 3 or 6-character hex color starting with '#'.
     * @param float  $amount 0-1, where 0 = no change, 1 = black.
     */
    private function darkenColor(string $hex, float $amount): ?string
    {
        $hex = trim($hex);
        if (!preg_match('/^#([0-9a-f]{3}|[0-9a-f]{6})$/i', $hex)) {
            return null;
        }

        $normalized = strlen($hex) === 4
            ? '#'.preg_replace('/([0-9a-f])/i', '$1$1', substr($hex, 1))
            : $hex;

        $r = hexdec(substr($normalized, 1, 2));
        $g = hexdec(substr($normalized, 3, 2));
        $b = hexdec(substr($normalized, 5, 2));

        $factor = max(0, min(1, $amount));
        $r = (int) round($r * (1 - $factor));
        $g = (int) round($g * (1 - $factor));
        $b = (int) round($b * (1 - $factor));

        return sprintf('#%02x%02x%02x', $r, $g, $b);
    }

    private function resolveLogoUrl(?Dealer $dealer): string
    {
        $path = trim((string) ($dealer?->logo_path ?? ''));

        if ($path !== '') {
            // Always return a path relative to the current host to avoid
            // mismatches between APP_URL and the actual domain (e.g. 127.0.0.1 vs localhost).
            return '/storage/'.$path;
        }

        // Fallback to the original MTT logo asset.
        return asset('images/mega-theron-logo.png');
    }

    private function resolveFaviconUrl(?Dealer $dealer): string
    {
        $path = trim((string) ($dealer?->favicon_path ?? ''));
        // Use millisecond precision to avoid "same-second" caching issues.
        $version = $dealer?->updated_at?->valueOf() ?? null;

        if ($path !== '') {
            // Use asset() so paths remain correct on subdirectories / different hosts.
            $url = asset('storage/'.$path);
            $versionKey = $version ? ($version.'-'.substr(sha1($path), 0, 8)) : null;

            return $versionKey ? ($url.'?v='.$versionKey) : $url;
        }

        // Platform default favicon. If it doesn't exist (local dev misconfig),
        // fall back to a stable image to avoid broken UI.
        $fallbackFile = public_path('favicon.ico');
        $fallback = file_exists($fallbackFile)
            ? asset('favicon.ico')
            : asset('images/mega-theron-logo.png');

        return $version ? ($fallback.'?v='.$version) : $fallback;
    }

    private function preset(string $key): ?array
    {
        $presets = (array) config('mtt_dealer_themes.presets', []);
        $preset = $presets[$key] ?? null;

        return is_array($preset) ? $preset : null;
    }

    private function pick(?string ...$values): ?string
    {
        foreach ($values as $value) {
            if (! is_string($value)) {
                continue;
            }
            $trimmed = trim($value);
            if ($trimmed !== '') {
                return $trimmed;
            }
        }
        return null;
    }

    private function currentDealer(): ?Dealer
    {
        static $cached = null;
        static $resolved = false;

        if ($resolved) {
            return $cached;
        }
        $resolved = true;

        $dealerIdFromSession = session('current_dealer_id');
        $dealerId = $dealerIdFromSession ?: (auth()->check() ? auth()->user()->dealer_id : null);

        if ($dealerId) {
            $cached = Dealer::query()->find($dealerId);
        }

        if (! $cached) {
            $cached = Dealer::query()->where('is_default', true)->first();
        }

        return $cached;
    }
}

