<?php
declare(strict_types=1);

namespace ROITheme\Public\Hero\Infrastructure\Ui;

use ROITheme\Shared\Domain\Contracts\RendererInterface;
use ROITheme\Shared\Domain\Contracts\CSSGeneratorInterface;
use ROITheme\Shared\Domain\Entities\Component;
use ROITheme\Shared\Infrastructure\Services\PageVisibilityHelper;

/**
 * Class HeroRenderer
 *
 * Renderizador del componente Hero para el frontend.
 *
 * Responsabilidades:
 * - Renderizar HTML del hero section con título del post/página
 * - Mostrar badges de categorías (dinámicos desde WordPress)
 * - Delegar generación de CSS a CSSGeneratorInterface
 * - Validar visibilidad (is_enabled, show_on_pages, responsive)
 * - Manejar visibilidad responsive con clases Bootstrap
 *
 * NO responsable de:
 * - Generar string CSS (delega a CSSGeneratorService)
 * - Persistir datos
 * - Lógica de negocio
 *
 * Cumple con:
 * - DIP: Recibe CSSGeneratorInterface por constructor
 * - SRP: Una responsabilidad (renderizar hero)
 * - Clean Architecture: Infrastructure puede usar WordPress
 *
 * @package ROITheme\Public\Hero\Infrastructure\Ui
 */
final class HeroRenderer implements RendererInterface
{
    private const COMPONENT_NAME = 'hero';

    /**
     * @param CSSGeneratorInterface $cssGenerator Servicio de generación de CSS
     */
    public function __construct(
        private CSSGeneratorInterface $cssGenerator
    ) {}

    public function render(Component $component): string
    {
        $data = $component->getData();

        if (!$this->isEnabled($data)) {
            return '';
        }

        if (!PageVisibilityHelper::shouldShow(self::COMPONENT_NAME)) {
            return '';
        }

        $html = $this->buildHTML($data);

        // Si is_critical=true, CSS ya fue inyectado en <head> por CriticalCSSService
        $isCritical = $data['visibility']['is_critical'] ?? false;

        if ($isCritical) {
            return $html; // Solo HTML, sin CSS inline
        }

        // CSS inline para componentes no críticos
        $css = $this->generateCSS($data);
        return sprintf("<style>%s</style>\n%s", $css, $html);
    }

    public function supports(string $componentType): bool
    {
        return $componentType === self::COMPONENT_NAME;
    }

    private function isEnabled(array $data): bool
    {
        return ($data['visibility']['is_enabled'] ?? false) === true;
    }

    /**
     * Generar CSS usando CSSGeneratorService
     *
     * Este método es público para que CriticalCSSService pueda
     * generar CSS crítico antes de wp_head sin duplicar lógica.
     *
     * @param array $data Datos del componente
     * @return string CSS generado
     */
    public function generateCSS(array $data): string
    {
        $colors = $data['colors'] ?? [];
        $typography = $data['typography'] ?? [];
        $spacing = $data['spacing'] ?? [];
        $effects = $data['visual_effects'] ?? [];
        $visibility = $data['visibility'] ?? [];

        $gradientStart = $colors['gradient_start'] ?? '#1e3a5f';
        $gradientEnd = $colors['gradient_end'] ?? '#2c5282';
        $titleColor = $colors['title_color'] ?? '#FFFFFF';
        $badgeBgColor = $colors['badge_bg_color'] ?? '#FFFFFF';
        $badgeTextColor = $colors['badge_text_color'] ?? '#FFFFFF';
        $badgeIconColor = $colors['badge_icon_color'] ?? '#FFB800';
        $badgeHoverBg = $colors['badge_hover_bg'] ?? '#FF8600';

        $titleFontSize = $typography['title_font_size'] ?? '2.5rem';
        $titleFontSizeMobile = $typography['title_font_size_mobile'] ?? '1.75rem';
        $titleFontWeight = $typography['title_font_weight'] ?? '700';
        $titleLineHeight = $typography['title_line_height'] ?? '1.4';
        $badgeFontSize = $typography['badge_font_size'] ?? '0.813rem';

        $paddingVertical = $spacing['padding_vertical'] ?? '3rem';
        $marginBottom = $spacing['margin_bottom'] ?? '1.5rem';
        $badgePadding = $spacing['badge_padding'] ?? '0.375rem 0.875rem';
        $badgeBorderRadius = $spacing['badge_border_radius'] ?? '20px';
        $minHeight = $spacing['min_height'] ?? '120px';
        $titleMinHeight = $spacing['title_min_height'] ?? '3rem';
        $badgeMinHeight = $spacing['badge_min_height'] ?? '32px';

        $boxShadow = $effects['box_shadow'] ?? '0 4px 16px rgba(30, 58, 95, 0.25)';
        $titleTextShadow = $effects['title_text_shadow'] ?? '1px 1px 2px rgba(0, 0, 0, 0.2)';
        $badgeBackdropBlur = $effects['badge_backdrop_blur'] ?? '10px';

        $showOnDesktop = $visibility['show_on_desktop'] ?? true;
        $showOnMobile = $visibility['show_on_mobile'] ?? true;

        $cssRules = [];

        $cssRules[] = $this->cssGenerator->generate('.hero-section', [
            'background' => "linear-gradient(135deg, {$gradientStart} 0%, {$gradientEnd} 100%)",
            'box-shadow' => $boxShadow,
            'padding' => "{$paddingVertical} 0",
            'margin-bottom' => $marginBottom,
            'min-height' => $minHeight,
            'display' => 'flex',
            'align-items' => 'center',
            'justify-content' => 'center',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.hero-section__title', [
            'color' => "{$titleColor} !important",
            'font-weight' => $titleFontWeight,
            'font-size' => $titleFontSize,
            'line-height' => $titleLineHeight,
            'text-shadow' => $titleTextShadow,
            'margin-bottom' => '0',
            'text-align' => 'center',
            'min-height' => $titleMinHeight,
        ]);

        // Contenedor de badges - altura minima para prevenir CLS
        $cssRules[] = $this->cssGenerator->generate('.hero-section .mb-3.d-flex', [
            'min-height' => '40px',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.hero-section__badge', [
            'background' => $this->hexToRgba($badgeBgColor, 0.15),
            'backdrop-filter' => "blur({$badgeBackdropBlur})",
            '-webkit-backdrop-filter' => "blur({$badgeBackdropBlur})",
            'border' => '1px solid ' . $this->hexToRgba($badgeBgColor, 0.2),
            'color' => $this->hexToRgba($badgeTextColor, 0.95),
            'padding' => $badgePadding,
            'border-radius' => $badgeBorderRadius,
            'font-size' => $badgeFontSize,
            'font-weight' => '500',
            'text-decoration' => 'none',
            'display' => 'inline-block',
            'transition' => 'all 0.3s ease',
            'min-height' => $badgeMinHeight,
        ]);

        $cssRules[] = $this->cssGenerator->generate('.hero-section__badge:hover', [
            'background' => $this->hexToRgba($badgeHoverBg, 0.2),
            'border-color' => $this->hexToRgba($badgeHoverBg, 0.4),
            'color' => '#ffffff',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.hero-section__badge i', [
            'color' => $badgeIconColor,
        ]);

        $cssRules[] = "@media (max-width: 767.98px) {
            .hero-section__title {
                font-size: {$titleFontSizeMobile};
            }
        }";

        if (!$showOnMobile) {
            $cssRules[] = "@media (max-width: 767.98px) {
                .hero-section { display: none !important; }
            }";
        }

        if (!$showOnDesktop) {
            $cssRules[] = "@media (min-width: 768px) {
                .hero-section { display: none !important; }
            }";
        }

        return implode("\n", $cssRules);
    }

    private function buildHTML(array $data): string
    {
        $content = $data['content'] ?? [];
        $showCategories = $content['show_categories'] ?? true;
        $showBadgeIcon = $content['show_badge_icon'] ?? true;
        $badgeIconClass = $content['badge_icon_class'] ?? 'bi-folder-fill';
        $titleTag = $content['title_tag'] ?? 'h1';

        $allowedTags = ['h1', 'h2', 'div'];
        if (!in_array($titleTag, $allowedTags, true)) {
            $titleTag = 'h1';
        }

        $title = is_singular() ? get_the_title() : '';
        if (empty($title)) {
            $title = wp_title('', false);
        }

        $html = '<div class="container-fluid hero-section">';
        $html .= '<div class="container">';

        if ($showCategories && is_single()) {
            $categories = get_the_category();
            if (!empty($categories)) {
                $html .= '<div class="mb-3 d-flex justify-content-center">';
                $html .= '<div class="d-flex gap-2 flex-wrap justify-content-center">';

                foreach ($categories as $category) {
                    $categoryLink = esc_url(get_category_link($category->term_id));
                    $categoryName = esc_html($category->name);
                    $iconHtml = $showBadgeIcon
                        ? '<i class="bi ' . esc_attr($badgeIconClass) . ' me-1"></i>'
                        : '';

                    $html .= sprintf(
                        '<a href="%s" class="hero-section__badge">%s%s</a>',
                        $categoryLink,
                        $iconHtml,
                        $categoryName
                    );
                }

                $html .= '</div>';
                $html .= '</div>';
            }
        }

        $html .= sprintf(
            '<%s class="hero-section__title">%s</%s>',
            $titleTag,
            esc_html($title),
            $titleTag
        );

        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    private function hexToRgba(string $hex, float $alpha): string
    {
        $hex = ltrim($hex, '#');

        if (strlen($hex) === 3) {
            $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
        }

        $r = hexdec(substr($hex, 0, 2));
        $g = hexdec(substr($hex, 2, 2));
        $b = hexdec(substr($hex, 4, 2));

        return "rgba({$r}, {$g}, {$b}, {$alpha})";
    }

    /**
     * Genera clases Bootstrap de visibilidad responsive
     *
     * @param bool $desktop Si debe mostrarse en desktop
     * @param bool $mobile Si debe mostrarse en mobile
     * @return string|null Clases Bootstrap o null si visible en todos
     */
    private function getVisibilityClasses(bool $desktop, bool $mobile): ?string
    {
        if ($desktop && $mobile) {
            return null;
        }

        if ($desktop && !$mobile) {
            return 'd-none d-md-block';
        }

        if (!$desktop && $mobile) {
            return 'd-block d-md-none';
        }

        return 'd-none';
    }
}
