<?php

declare(strict_types=1);

namespace App\Application\Admin\ValueObjects;

use App\Framework\Design\ValueObjects\CssColor;
use App\Framework\Design\ValueObjects\DesignToken;
use App\Framework\Design\ValueObjects\ColorFormat;

/**
 * Admin Token Registry
 *
 * Central registry for all admin design tokens.
 * Uses framework's DesignToken system for compatibility.
 */
final readonly class AdminTokenRegistry
{
    /**
     * @var array<string, DesignToken>
     */
    private array $tokens;

    public function __construct()
    {
        $this->tokens = $this->initializeTokens();
    }

    /**
     * Get token by name
     */
    public function get(string $name): ?DesignToken
    {
        return $this->tokens[$name] ?? null;
    }

    /**
     * Get all tokens
     * @return array<string, DesignToken>
     */
    public function all(): array
    {
        return $this->tokens;
    }

    /**
     * Get tokens by category
     * @return array<string, DesignToken>
     */
    public function byCategory(string $category): array
    {
        return array_filter(
            $this->tokens,
            fn(DesignToken $token) => str_starts_with($token->name, $category . '-')
        );
    }

    /**
     * Get all color tokens
     * @return array<string, DesignToken>
     */
    public function colors(): array
    {
        return array_filter(
            $this->tokens,
            fn(DesignToken $token) => $token->value instanceof CssColor
        );
    }

    /**
     * Get all spacing tokens
     * @return array<string, DesignToken>
     */
    public function spacing(): array
    {
        return $this->byCategory('spacing');
    }

    /**
     * Generate CSS custom properties
     */
    public function toCss(): string
    {
        $css = ":root {\n";

        foreach ($this->tokens as $token) {
            $css .= "    " . $token->toCssCustomProperty() . "\n";
        }

        $css .= "}\n";

        return $css;
    }

    /**
     * Generate dark mode CSS overrides
     */
    public function toDarkModeCss(): string
    {
        $css = "@media (prefers-color-scheme: dark) {\n";
        $css .= "    :root {\n";

        foreach ($this->colors() as $token) {
            $darkColor = $this->getDarkModeColor($token);
            if ($darkColor) {
                $css .= "        --{$token->name}: {$darkColor->toString()};\n";
            }
        }

        $css .= "    }\n";
        $css .= "}\n";

        return $css;
    }

    /**
     * Initialize all admin design tokens
     * @return array<string, DesignToken>
     */
    private function initializeTokens(): array
    {
        return [
            // Background Colors
            'admin-bg-primary' => DesignToken::color(
                'admin-bg-primary',
                new CssColor('oklch(98% 0.01 280)', ColorFormat::OKLCH),
                'Primary background color'
            ),
            'admin-bg-secondary' => DesignToken::color(
                'admin-bg-secondary',
                new CssColor('oklch(95% 0.01 280)', ColorFormat::OKLCH),
                'Secondary background color'
            ),
            'admin-bg-tertiary' => DesignToken::color(
                'admin-bg-tertiary',
                new CssColor('oklch(92% 0.01 280)', ColorFormat::OKLCH),
                'Tertiary background color'
            ),

            // Sidebar Colors
            'admin-sidebar-bg' => DesignToken::color(
                'admin-sidebar-bg',
                new CssColor('oklch(25% 0.02 280)', ColorFormat::OKLCH),
                'Sidebar background color'
            ),
            'admin-sidebar-text' => DesignToken::color(
                'admin-sidebar-text',
                new CssColor('oklch(90% 0.01 280)', ColorFormat::OKLCH),
                'Sidebar text color'
            ),
            'admin-sidebar-text-hover' => DesignToken::color(
                'admin-sidebar-text-hover',
                new CssColor('oklch(100% 0 0)', ColorFormat::OKLCH),
                'Sidebar text hover color'
            ),
            'admin-sidebar-active' => DesignToken::color(
                'admin-sidebar-active',
                new CssColor('oklch(45% 0.15 280)', ColorFormat::OKLCH),
                'Sidebar active item color'
            ),
            'admin-sidebar-border' => DesignToken::color(
                'admin-sidebar-border',
                new CssColor('oklch(30% 0.02 280)', ColorFormat::OKLCH),
                'Sidebar border color'
            ),

            // Header Colors
            'admin-header-bg' => DesignToken::color(
                'admin-header-bg',
                new CssColor('oklch(100% 0 0)', ColorFormat::OKLCH),
                'Header background color'
            ),
            'admin-header-border' => DesignToken::color(
                'admin-header-border',
                new CssColor('oklch(85% 0.01 280)', ColorFormat::OKLCH),
                'Header border color'
            ),
            'admin-header-text' => DesignToken::color(
                'admin-header-text',
                new CssColor('oklch(20% 0.02 280)', ColorFormat::OKLCH),
                'Header text color'
            ),

            // Content Colors
            'admin-content-bg' => DesignToken::color(
                'admin-content-bg',
                new CssColor('oklch(100% 0 0)', ColorFormat::OKLCH),
                'Content background color'
            ),
            'admin-content-text' => DesignToken::color(
                'admin-content-text',
                new CssColor('oklch(20% 0.02 280)', ColorFormat::OKLCH),
                'Content text color'
            ),

            // Interactive Colors
            'admin-link-color' => DesignToken::color(
                'admin-link-color',
                new CssColor('oklch(55% 0.2 260)', ColorFormat::OKLCH),
                'Link color'
            ),
            'admin-link-hover' => DesignToken::color(
                'admin-link-hover',
                new CssColor('oklch(45% 0.25 260)', ColorFormat::OKLCH),
                'Link hover color'
            ),
            'admin-link-active' => DesignToken::color(
                'admin-link-active',
                new CssColor('oklch(35% 0.3 260)', ColorFormat::OKLCH),
                'Link active color'
            ),

            // Accent Colors
            'admin-accent-primary' => DesignToken::color(
                'admin-accent-primary',
                new CssColor('oklch(60% 0.2 280)', ColorFormat::OKLCH),
                'Primary accent color'
            ),
            'admin-accent-success' => DesignToken::color(
                'admin-accent-success',
                new CssColor('oklch(65% 0.2 145)', ColorFormat::OKLCH),
                'Success accent color'
            ),
            'admin-accent-warning' => DesignToken::color(
                'admin-accent-warning',
                new CssColor('oklch(70% 0.2 85)', ColorFormat::OKLCH),
                'Warning accent color'
            ),
            'admin-accent-error' => DesignToken::color(
                'admin-accent-error',
                new CssColor('oklch(60% 0.25 25)', ColorFormat::OKLCH),
                'Error accent color'
            ),
            'admin-accent-info' => DesignToken::color(
                'admin-accent-info',
                new CssColor('oklch(65% 0.2 240)', ColorFormat::OKLCH),
                'Info accent color'
            ),

            // Border Colors
            'admin-border-light' => DesignToken::color(
                'admin-border-light',
                new CssColor('oklch(90% 0.01 280)', ColorFormat::OKLCH),
                'Light border color'
            ),
            'admin-border-medium' => DesignToken::color(
                'admin-border-medium',
                new CssColor('oklch(80% 0.02 280)', ColorFormat::OKLCH),
                'Medium border color'
            ),
            'admin-border-dark' => DesignToken::color(
                'admin-border-dark',
                new CssColor('oklch(70% 0.02 280)', ColorFormat::OKLCH),
                'Dark border color'
            ),

            // Focus/Hover States
            'admin-focus-ring' => DesignToken::color(
                'admin-focus-ring',
                new CssColor('oklch(55% 0.2 260)', ColorFormat::OKLCH),
                'Focus ring color'
            ),
            'admin-hover-overlay' => DesignToken::color(
                'admin-hover-overlay',
                new CssColor('oklch(0% 0 0 / 0.05)', ColorFormat::OKLCH),
                'Hover overlay color'
            ),

            // Spacing Tokens
            'spacing-xs' => DesignToken::spacing('spacing-xs', '0.25rem', 'Extra small spacing'),
            'spacing-sm' => DesignToken::spacing('spacing-sm', '0.5rem', 'Small spacing'),
            'spacing-md' => DesignToken::spacing('spacing-md', '1rem', 'Medium spacing'),
            'spacing-lg' => DesignToken::spacing('spacing-lg', '1.5rem', 'Large spacing'),
            'spacing-xl' => DesignToken::spacing('spacing-xl', '2rem', 'Extra large spacing'),
            'spacing-2xl' => DesignToken::spacing('spacing-2xl', '3rem', 'Double extra large spacing'),

            // Layout Spacing
            'spacing-sidebar' => DesignToken::spacing('spacing-sidebar', '250px', 'Sidebar width'),
            'spacing-sidebar-wide' => DesignToken::spacing('spacing-sidebar-wide', '280px', 'Sidebar width on wide screens'),
            'spacing-header' => DesignToken::spacing('spacing-header', '4rem', 'Header height'),
            'spacing-content-padding' => DesignToken::spacing('spacing-content-padding', '2rem', 'Content padding'),
            'spacing-content-max-width' => DesignToken::spacing('spacing-content-max-width', '1400px', 'Content maximum width'),

            // Typography Tokens
            'font-size-xs' => DesignToken::typography('font-size-xs', '0.75rem', 'Extra small font size'),
            'font-size-sm' => DesignToken::typography('font-size-sm', '0.875rem', 'Small font size'),
            'font-size-base' => DesignToken::typography('font-size-base', '1rem', 'Base font size'),
            'font-size-lg' => DesignToken::typography('font-size-lg', '1.125rem', 'Large font size'),
            'font-size-xl' => DesignToken::typography('font-size-xl', '1.25rem', 'Extra large font size'),
            'font-size-2xl' => DesignToken::typography('font-size-2xl', '1.5rem', 'Double extra large font size'),
            'font-size-3xl' => DesignToken::typography('font-size-3xl', '1.875rem', 'Triple extra large font size'),
        ];
    }

    /**
     * Get dark mode variant of a color
     */
    private function getDarkModeColor(DesignToken $token): ?CssColor
    {
        if (!($token->value instanceof CssColor)) {
            return null;
        }

        // Dark mode color mappings
        $darkModeMap = [
            // Backgrounds
            'admin-bg-primary' => 'oklch(20% 0.02 280)',
            'admin-bg-secondary' => 'oklch(23% 0.02 280)',
            'admin-bg-tertiary' => 'oklch(26% 0.02 280)',

            // Sidebar
            'admin-sidebar-bg' => 'oklch(15% 0.02 280)',
            'admin-sidebar-text' => 'oklch(75% 0.02 280)',
            'admin-sidebar-text-hover' => 'oklch(95% 0.01 280)',
            'admin-sidebar-active' => 'oklch(35% 0.2 280)',
            'admin-sidebar-border' => 'oklch(25% 0.02 280)',

            // Header
            'admin-header-bg' => 'oklch(18% 0.02 280)',
            'admin-header-border' => 'oklch(30% 0.02 280)',
            'admin-header-text' => 'oklch(90% 0.01 280)',

            // Content
            'admin-content-bg' => 'oklch(20% 0.02 280)',
            'admin-content-text' => 'oklch(90% 0.01 280)',

            // Interactive
            'admin-link-color' => 'oklch(70% 0.2 260)',
            'admin-link-hover' => 'oklch(80% 0.22 260)',
            'admin-link-active' => 'oklch(85% 0.25 260)',

            // Borders
            'admin-border-light' => 'oklch(30% 0.02 280)',
            'admin-border-medium' => 'oklch(35% 0.02 280)',
            'admin-border-dark' => 'oklch(40% 0.02 280)',

            // Focus
            'admin-focus-ring' => 'oklch(70% 0.2 260)',
            'admin-hover-overlay' => 'oklch(100% 0 0 / 0.05)',
        ];

        if (isset($darkModeMap[$token->name])) {
            return new CssColor($darkModeMap[$token->name], ColorFormat::OKLCH);
        }

        return null;
    }
}
