<?php
declare(strict_types=1);

namespace ROITheme\Public\Navbar\Infrastructure\Ui;

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

/**
 * NavbarRenderer - Renderiza el menú de navegación principal
 *
 * RESPONSABILIDAD: Generar HTML del menú de navegación WordPress
 *
 * CARACTERÍSTICAS:
 * - Integración con wp_nav_menu()
 * - Walker personalizado para Bootstrap 5
 * - Soporte para submenús desplegables
 * - Responsive con navbar-toggler
 *
 * Cumple con:
 * - DIP: Recibe CSSGeneratorInterface por constructor
 * - SRP: Una responsabilidad (renderizar navbar)
 * - Clean Architecture: Infrastructure puede usar WordPress
 *
 * @package ROITheme\Public\Navbar\Infrastructure\Ui
 */
final class NavbarRenderer implements RendererInterface
{
    private const COMPONENT_NAME = 'navbar';

    /**
     * @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->buildMenu($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);
    }

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

    private function shouldShowOnMobile(array $data): bool
    {
        return isset($data['visibility']['show_on_mobile']) &&
               $data['visibility']['show_on_mobile'] === 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
    {
        $css = '';

        // Obtener valores de configuración
        $stickyEnabled = $data['visibility']['sticky_enabled'] ?? true;
        $paddingVertical = $data['layout']['padding_vertical'] ?? '0.75rem 0';
        $zIndex = $data['layout']['z_index'] ?? '1030';

        $bgColor = $data['colors']['background_color'] ?? '#1e3a5f';
        $boxShadow = $data['colors']['box_shadow'] ?? '0 4px 12px rgba(30, 58, 95, 0.15)';

        $linkTextColor = $data['links']['text_color'] ?? '#FFFFFF';
        $linkHoverColor = $data['links']['hover_color'] ?? '#FF8600';
        $linkActiveColor = $data['links']['active_color'] ?? '#FF8600';
        $linkFontSize = $data['links']['font_size'] ?? '0.9rem';
        $linkFontWeight = $data['links']['font_weight'] ?? '500';
        $linkPadding = $data['links']['padding'] ?? '0.5rem 0.65rem';
        $linkBorderRadius = $data['links']['border_radius'] ?? '4px';
        $showUnderlineEffect = $data['links']['show_underline_effect'] ?? true;
        $underlineColor = $data['links']['underline_color'] ?? '#FF8600';

        // Estilos del navbar container
        $navbarStyles = [
            'background-color' => $bgColor . ' !important',
            'box-shadow' => $boxShadow,
            'padding' => $paddingVertical,
            'transition' => 'all 0.3s ease',
        ];

        if ($stickyEnabled) {
            $navbarStyles['position'] = 'sticky';
            $navbarStyles['top'] = '0';
            $navbarStyles['z-index'] = $zIndex;
        }

        $css .= $this->cssGenerator->generate('.navbar', $navbarStyles);

        // Efecto scrolled del navbar
        $css .= "\n" . $this->cssGenerator->generate('.navbar.scrolled', [
            'box-shadow' => '0 6px 20px rgba(30, 58, 95, 0.25)',
        ]);

        // Estilos de los enlaces del navbar
        $navLinkStyles = [
            'color' => 'rgba(255, 255, 255, 0.9) !important',
            'font-weight' => $linkFontWeight,
            'position' => 'relative',
            'padding' => $linkPadding . ' !important',
            'transition' => 'all 0.3s ease',
            'font-size' => $linkFontSize,
            'white-space' => 'nowrap',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .nav-link', $navLinkStyles);

        // Efecto de subrayado (::after pseudo-element)
        if ($showUnderlineEffect) {
            $css .= "\n.navbar .nav-link::after {";
            $css .= "\n    content: '';";
            $css .= "\n    position: absolute;";
            $css .= "\n    bottom: 0;";
            $css .= "\n    left: 50%;";
            $css .= "\n    transform: translateX(-50%) scaleX(0);";
            $css .= "\n    width: 80%;";
            $css .= "\n    height: 2px;";
            $css .= "\n    background: {$underlineColor};";
            $css .= "\n    transition: transform 0.3s ease;";
            $css .= "\n}";

            $css .= "\n.navbar .nav-link:hover::after {";
            $css .= "\n    transform: translateX(-50%) scaleX(1);";
            $css .= "\n}";
        }

        // Estilos hover y focus de los enlaces
        $navLinkHoverStyles = [
            'color' => $linkHoverColor . ' !important',
            'background-color' => 'rgba(255, 133, 0, 0.1)',
            'border-radius' => $linkBorderRadius,
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .nav-link:hover, .navbar .nav-link:focus', $navLinkHoverStyles);

        // Estilos de enlaces activos
        $navLinkActiveStyles = [
            'color' => $linkActiveColor . ' !important',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .nav-link.active, .navbar .nav-item.current-menu-item > .nav-link', $navLinkActiveStyles);

        // Estilos del dropdown menu
        $dropdownMaxHeight = $data['visual_effects']['dropdown_max_height'] ?? '300px';
        $dropdownStyles = [
            'background' => $data['visual_effects']['background_color'] ?? '#ffffff',
            'border' => 'none',
            'box-shadow' => $data['visual_effects']['shadow'] ?? '0 8px 24px rgba(0, 0, 0, 0.12)',
            'border-radius' => $data['visual_effects']['border_radius'] ?? '8px',
            'padding' => '0.5rem 0',
            'max-height' => $dropdownMaxHeight,
            'overflow-y' => 'auto',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .dropdown-menu', $dropdownStyles);

        // Hover en desktop para mostrar dropdown (sin necesidad de clic)
        $css .= "\n@media (min-width: 992px) {";
        $css .= "\n    .navbar .dropdown:hover > .dropdown-menu {";
        $css .= "\n        display: block;";
        $css .= "\n        margin-top: 0;";
        $css .= "\n    }";
        $css .= "\n}";

        // Estilos de items del dropdown
        $dropdownItemStyles = [
            'color' => $data['visual_effects']['item_color'] ?? '#495057',
            'padding' => $data['visual_effects']['item_padding'] ?? '0.625rem 1.25rem',
            'transition' => 'all 0.3s ease',
            'font-weight' => '500',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .dropdown-item', $dropdownItemStyles);

        // Estilos hover de items del dropdown
        $dropdownItemHoverStyles = [
            'background-color' => $data['visual_effects']['item_hover_background'] ?? 'rgba(255, 133, 0, 0.1)',
            'color' => $linkHoverColor,
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .dropdown-item:hover, .navbar .dropdown-item:focus', $dropdownItemHoverStyles);

        // Estilos del brand (texto)
        $brandStyles = [
            'color' => ($data['media']['brand_color'] ?? '#FFFFFF') . ' !important',
            'font-weight' => '700',
            'font-size' => $data['media']['brand_font_size'] ?? '1.5rem',
            'transition' => 'color 0.3s ease',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .navbar-brand, .navbar .roi-navbar-brand', $brandStyles);

        // Estilos hover del brand
        $brandHoverStyles = [
            'color' => ($data['media']['brand_hover_color'] ?? '#FF8600') . ' !important',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .navbar-brand:hover, .navbar .roi-navbar-brand:hover', $brandHoverStyles);

        // Estilos del logo (imagen)
        $logoStyles = [
            'height' => $data['media']['logo_height'] ?? '40px',
            'width' => 'auto',
        ];
        $css .= "\n" . $this->cssGenerator->generate('.navbar .roi-navbar-logo', $logoStyles);

        return $css;
    }

    private function buildMenu(array $data): string
    {
        $menuLocation = $data['behavior']['menu_location'] ?? 'primary';
        $enableDropdowns = $data['behavior']['enable_dropdowns'] ?? true;
        $mobileBreakpoint = $data['behavior']['mobile_breakpoint'] ?? 'lg';

        $ulClass = 'navbar-nav mb-2 mb-lg-0';

        $args = [
            'theme_location' => $menuLocation === 'custom' ? '' : $menuLocation,
            'menu' => $menuLocation === 'custom' ? ($data['behavior']['custom_menu_id'] ?? 0) : '',
            'container' => false,
            'menu_class' => $ulClass,
            'fallback_cb' => '__return_false',
            'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
            'depth' => $enableDropdowns ? 2 : 1,
            'walker' => new ROI_Bootstrap_Nav_Walker()
        ];

        ob_start();
        wp_nav_menu($args);
        return ob_get_clean();
    }

    /**
     * Obtiene las clases CSS de Bootstrap para visibilidad responsive
     *
     * Implementa tabla de decisión según especificación:
     * - Desktop Y Mobile = null (visible en ambos)
     * - Solo Desktop = 'd-none d-lg-block'
     * - Solo Mobile = 'd-lg-none'
     * - Ninguno = 'd-none' (oculto)
     *
     * @param bool $desktop Mostrar en desktop
     * @param bool $mobile Mostrar en mobile
     * @return string|null Clases CSS o null si visible en ambos
     */
    private function getVisibilityClasses(bool $desktop, bool $mobile): ?string
    {
        if ($desktop && $mobile) {
            return null; // Sin clases = visible siempre
        }
        if ($desktop && !$mobile) {
            return 'd-none d-lg-block';
        }
        if (!$desktop && $mobile) {
            return 'd-lg-none';
        }
        return 'd-none';
    }

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

/**
 * Custom Walker for Bootstrap 5 Navigation
 *
 * RESPONSABILIDAD: Adaptar wp_nav_menu() a Bootstrap 5
 *
 * CARACTERÍSTICAS:
 * - Clases Bootstrap 5 (.nav-item, .nav-link, .dropdown)
 * - Atributos data-bs-toggle para dropdowns
 * - Soporte para current-menu-item
 */
class ROI_Bootstrap_Nav_Walker extends Walker_Nav_Menu
{
    public function start_lvl(&$output, $depth = 0, $args = null)
    {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"dropdown-menu\">\n";
    }

    public function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
    {
        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        $classes = empty($item->classes) ? [] : (array) $item->classes;
        $classes[] = 'nav-item';

        if ($args->walker->has_children) {
            $classes[] = 'dropdown';
        }

        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args, $depth));
        $class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';

        $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth);
        $id = $id ? ' id="' . esc_attr($id) . '"' : '';

        $output .= $indent . '<li' . $id . $class_names . '>';

        $atts = [];
        $atts['title'] = !empty($item->attr_title) ? $item->attr_title : '';
        $atts['target'] = !empty($item->target) ? $item->target : '';
        $atts['rel'] = !empty($item->xfn) ? $item->xfn : '';
        $atts['href'] = !empty($item->url) ? $item->url : '';

        if ($depth === 0) {
            $atts['class'] = 'nav-link';
            if ($args->walker->has_children) {
                $atts['class'] .= ' dropdown-toggle';
                // Only add data-bs-toggle if no real URL (allows click navigation on desktop)
                // CSS hover handles showing dropdown, data-bs-toggle only needed for mobile
                $url = !empty($item->url) ? $item->url : '';
                if (empty($url) || $url === '#' || $url === '#!') {
                    $atts['data-bs-toggle'] = 'dropdown';
                }
                $atts['role'] = 'button';
                $atts['aria-expanded'] = 'false';
            }
        } else {
            $atts['class'] = 'dropdown-item';
        }

        if (in_array('current-menu-item', $classes)) {
            $atts['class'] .= ' active';
        }

        $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args, $depth);

        $attributes = '';
        foreach ($atts as $attr => $value) {
            if (!empty($value)) {
                $value = ('href' === $attr) ? esc_url($value) : esc_attr($value);
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }

        $title = apply_filters('the_title', $item->title, $item->ID);
        $title = apply_filters('nav_menu_item_title', $title, $item, $args, $depth);

        $item_output = $args->before;
        $item_output .= '<a' . $attributes . '>';
        $item_output .= $args->link_before . $title . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }
}
