<?php
declare(strict_types=1);

namespace ROITheme\Public\AdsensePlacement\Infrastructure\Ui;

use ROITheme\Shared\Domain\Contracts\CSSGeneratorInterface;
use ROITheme\Shared\Infrastructure\Services\PageVisibilityHelper;

/**
 * Renderer para slots de AdSense
 *
 * Responsabilidad:
 * - Generar HTML de bloques de anuncios
 * - Aplicar visibilidad desktop/mobile
 * - NO hardcodear CSS (usar CSSGeneratorInterface)
 */
final class AdsensePlacementRenderer
{
    public function __construct(
        private CSSGeneratorInterface $cssGenerator
    ) {}

    /**
     * Identifica el componente que soporta
     */
    public function supports(string $componentType): bool
    {
        return $componentType === 'adsense-placement';
    }

    /**
     * Renderiza un slot de anuncio
     *
     * @param array $settings Configuracion desde BD
     * @param string $location Ubicacion (post-top, sidebar, etc.)
     * @return string HTML del anuncio o vacio
     */
    public function renderSlot(array $settings, string $location): string
    {
        // 0. Verificar visibilidad por tipo de página y exclusiones (Plan 99.10/99.11)
        if (!PageVisibilityHelper::shouldShow('adsense-placement')) {
            return '';
        }

        // 1. Validar is_enabled
        if (!($settings['visibility']['is_enabled'] ?? false)) {
            return '';
        }

        // 2. Calcular clases de visibilidad
        $visibilityClasses = $this->getVisibilityClasses(
            $settings['visibility']['show_on_desktop'] ?? true,
            $settings['visibility']['show_on_mobile'] ?? true
        );

        if ($visibilityClasses === null) {
            return ''; // Ambos false = no renderizar
        }

        // 3. Obtener configuracion de la ubicacion
        $locationConfig = $this->getLocationConfig($settings, $location);
        if (!$locationConfig['enabled']) {
            return '';
        }

        // 4. Generar CSS (usando CSSGeneratorService)
        $css = $this->cssGenerator->generate(
            ".roi-ad-slot",
            [
                'display' => 'block',
                'width' => '100%',
                'min_width' => '300px',
                'margin_top' => '1.5rem',
                'margin_bottom' => '1.5rem',
                'text_align' => 'center',
            ]
        );

        // 5. Generar HTML del anuncio
        $html = $this->buildAdHTML(
            $settings,
            $locationConfig['format'],
            $location,
            $visibilityClasses
        );

        return "<style>{$css}</style>\n{$html}";
    }

    /**
     * Tabla de decision Bootstrap para visibilidad
     */
    private function getVisibilityClasses(bool $desktop, bool $mobile): ?string
    {
        if (!$desktop && !$mobile) {
            return null;
        }
        if (!$desktop && $mobile) {
            return 'd-lg-none';
        }
        if ($desktop && !$mobile) {
            return 'd-none d-lg-block';
        }
        return '';
    }

    /**
     * Obtiene configuracion de una ubicacion especifica
     */
    private function getLocationConfig(array $settings, string $location): array
    {
        $locationKey = str_replace('-', '_', $location);

        // Manejar ubicaciones de in-content (post_content_1, post_content_2, etc.)
        if (preg_match('/^post_content_(\d+)$/', $locationKey, $matches)) {
            // In-content ads heredan la configuracion de post_content
            return [
                'enabled' => $settings['behavior']['post_content_enabled'] ?? false,
                'format' => $settings['behavior']['post_content_format'] ?? 'in-article',
            ];
        }

        // Mapeo de ubicaciones a grupos y campos
        $locationMap = [
            'post_top' => ['group' => 'behavior', 'enabled' => 'post_top_enabled', 'format' => 'post_top_format'],
            'post_bottom' => ['group' => 'behavior', 'enabled' => 'post_bottom_enabled', 'format' => 'post_bottom_format'],
            'after_related' => ['group' => 'behavior', 'enabled' => 'after_related_enabled', 'format' => 'after_related_format'],
            'archive_top' => ['group' => 'layout', 'enabled' => 'archive_top_enabled', 'format' => 'archive_format'],
            'archive_between' => ['group' => 'layout', 'enabled' => 'archive_between_enabled', 'format' => 'archive_format'],
            'archive_bottom' => ['group' => 'layout', 'enabled' => 'archive_bottom_enabled', 'format' => 'archive_format'],
            'header_below' => ['group' => 'layout', 'enabled' => 'header_below_enabled', 'format' => 'global_format'],
            'footer_above' => ['group' => 'layout', 'enabled' => 'footer_above_enabled', 'format' => 'global_format'],
        ];

        if (!isset($locationMap[$locationKey])) {
            return ['enabled' => false, 'format' => 'auto'];
        }

        $map = $locationMap[$locationKey];
        $group = $settings[$map['group']] ?? [];

        return [
            'enabled' => $group[$map['enabled']] ?? false,
            'format' => $group[$map['format']] ?? 'auto',
        ];
    }

    /**
     * Genera HTML del bloque de anuncio
     */
    private function buildAdHTML(array $settings, string $format, string $location, string $visClasses): string
    {
        $publisherId = esc_attr($settings['content']['publisher_id'] ?? '');
        $delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;

        if (empty($publisherId)) {
            return '';
        }

        // Obtener slot segun formato
        $slotId = $this->getSlotByFormat($settings, $format);
        if (empty($slotId)) {
            return '';
        }

        $scriptType = $delayEnabled ? 'text/plain' : 'text/javascript';
        $dataAttr = $delayEnabled ? ' data-adsense-push' : '';
        $locationClass = 'roi-ad-' . esc_attr(str_replace('_', '-', $location));

        return $this->generateAdMarkup($format, $publisherId, $slotId, $locationClass, $visClasses, $scriptType, $dataAttr);
    }

    /**
     * Obtiene el slot ID segun el formato
     */
    private function getSlotByFormat(array $settings, string $format): string
    {
        $content = $settings['content'] ?? [];

        return match($format) {
            'display', 'display-large', 'display-square' => $content['slot_display'] ?? '',
            'in-article' => $content['slot_inarticle'] ?? '',
            'autorelaxed' => $content['slot_autorelaxed'] ?? '',
            default => $content['slot_auto'] ?? '',
        };
    }

    /**
     * Genera el markup HTML segun formato de anuncio
     *
     * EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense
     * ----------------------------------------------------------------
     * Los atributos style="display:inline-block", style="display:block",
     * style="text-align:center", etc. son ESPECIFICACION DE GOOGLE y NO
     * pueden generarse via CSSGenerator.
     *
     * Documentacion oficial:
     * - https://support.google.com/adsense/answer/9274516
     * - https://support.google.com/adsense/answer/9183460
     *
     * Estos estilos son necesarios para que AdSense funcione correctamente
     * y son inyectados tal como Google los especifica en su documentacion.
     */
    private function generateAdMarkup(
        string $format,
        string $client,
        string $slot,
        string $locationClass,
        string $visClasses,
        string $scriptType,
        string $dataAttr
    ): string {
        $allClasses = trim("{$locationClass} {$visClasses}");

        return match($format) {
            'display' => $this->adDisplay($client, $slot, 728, 90, $allClasses, $scriptType, $dataAttr),
            'display-large' => $this->adDisplay($client, $slot, 970, 250, $allClasses, $scriptType, $dataAttr),
            'display-square' => $this->adDisplay($client, $slot, 300, 250, $allClasses, $scriptType, $dataAttr),
            'in-article' => $this->adInArticle($client, $slot, $allClasses, $scriptType, $dataAttr),
            'autorelaxed' => $this->adAutorelaxed($client, $slot, $allClasses, $scriptType, $dataAttr),
            default => $this->adAuto($client, $slot, $allClasses, $scriptType, $dataAttr),
        };
    }

    private function adDisplay(string $c, string $s, int $w, int $h, string $cl, string $t, string $a): string
    {
        return sprintf(
            '<div class="roi-ad-slot %s">
                <ins class="adsbygoogle" style="display:inline-block;width:%dpx;height:%dpx"
                     data-ad-client="%s" data-ad-slot="%s"></ins>
                <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
            </div>',
            esc_attr($cl), $w, $h, esc_attr($c), esc_attr($s), $t, $a
        );
    }

    private function adAuto(string $c, string $s, string $cl, string $t, string $a): string
    {
        return sprintf(
            '<div class="roi-ad-slot %s">
                <ins class="adsbygoogle" style="display:block;min-height:250px"
                     data-ad-client="%s" data-ad-slot="%s"
                     data-ad-format="auto" data-full-width-responsive="true"></ins>
                <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
            </div>',
            esc_attr($cl), esc_attr($c), esc_attr($s), $t, $a
        );
    }

    private function adInArticle(string $c, string $s, string $cl, string $t, string $a): string
    {
        return sprintf(
            '<div class="roi-ad-slot %s">
                <ins class="adsbygoogle" style="display:block;text-align:center;min-height:200px"
                     data-ad-layout="in-article" data-ad-format="fluid"
                     data-ad-client="%s" data-ad-slot="%s"></ins>
                <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
            </div>',
            esc_attr($cl), esc_attr($c), esc_attr($s), $t, $a
        );
    }

    private function adAutorelaxed(string $c, string $s, string $cl, string $t, string $a): string
    {
        return sprintf(
            '<div class="roi-ad-slot %s">
                <ins class="adsbygoogle" style="display:block;min-height:280px"
                     data-ad-format="autorelaxed"
                     data-ad-client="%s" data-ad-slot="%s"></ins>
                <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
            </div>',
            esc_attr($cl), esc_attr($c), esc_attr($s), $t, $a
        );
    }

    /**
     * Renderiza Rail Ads (anuncios fijos en margenes laterales)
     * Se inyectan via wp_footer y usan position: fixed
     */
    public function renderRailAds(array $settings): string
    {
        // Verificar si Rail Ads estan habilitados
        if (!($settings['visibility']['is_enabled'] ?? false)) {
            return '';
        }
        if (!($settings['behavior']['rail_ads_enabled'] ?? false)) {
            return '';
        }

        $publisherId = esc_attr($settings['content']['publisher_id'] ?? '');
        $slotId = $settings['content']['slot_skyscraper'] ?? '';

        if (empty($publisherId) || empty($slotId)) {
            return '';
        }

        $leftEnabled = ($settings['behavior']['rail_left_enabled'] ?? true) === true;
        $rightEnabled = ($settings['behavior']['rail_right_enabled'] ?? true) === true;
        $format = $settings['behavior']['rail_format'] ?? 'skyscraper';
        // Agregar 15px de margen para evitar solapamiento con hero
        $topOffset = (int)($settings['behavior']['rail_top_offset'] ?? 300) + 15;
        $delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;

        // Altura del rail segun formato seleccionado
        // El ancho es responsive (se ajusta automaticamente al espacio disponible)
        $height = match($format) {
            'h250' => 250,
            'h300' => 300,
            'h400' => 400,
            'h500' => 500,
            'h600' => 600,
            'h700' => 700,
            'h800' => 800,
            'h1050' => 1050,
            // Legacy keys para compatibilidad con valores anteriores
            'skyscraper', 'slim-large', 'w130-h600', 'w140-h600', 'w150-h600' => 600,
            'slim-small', 'w130-h300', 'w140-h300', 'w150-h300' => 300,
            'slim-medium', 'w130-h400', 'w140-h400', 'w150-h400' => 400,
            'slim-xlarge' => 700,
            'wide-skyscraper' => 800,
            'w300-h250' => 250,
            'half-page' => 600,
            'large-skyscraper' => 1050,
            default => 600,
        };

        $scriptType = $delayEnabled ? 'text/plain' : 'text/javascript';
        $dataAttr = $delayEnabled ? ' data-adsense-push' : '';

        // === CSS via CSSGenerator (NO hardcodeado) ===
        $cssRules = [];

        // Estilos base para Rail Ads - RESPONSIVE
        // El ancho se calcula automaticamente para llenar el espacio disponible
        // Formula: (viewport - container) / 2 - margen_exterior(10px) - gap_interior(10px)
        $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad', [
            'position' => 'fixed',
            'top' => $topOffset . 'px',
            'width' => 'calc((100vw - var(--roi-container-width-numeric, 1320px)) / 2 - 20px)',
            'height' => $height . 'px',
            'display' => 'flex',
            'align-items' => 'flex-start',
            'z-index' => '100',
            'transition' => 'top 0.2s ease-out, opacity 0.3s ease-out',
        ]);

        // Rail izquierdo
        $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-left', [
            'left' => '0px',
            'justify-content' => 'flex-end',
            'padding-left' => '5px',
        ]);

        // Rail derecho
        $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-right', [
            'right' => '0px',
            'justify-content' => 'flex-start',
            'padding-right' => '5px',
        ]);

        // Asegurar que el anuncio no desborde el container
        $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad ins.adsbygoogle', [
            'max-width' => '100%',
        ]);

        // Media query para ocultar en pantallas donde no hay espacio suficiente
        // Mostrar a partir de 1400px para dar mas flexibilidad
        $cssRules[] = "@media (max-width: 1399px) {
            .roi-rail-ad { display: none !important; }
        }";

        $css = implode("\n", $cssRules);

        // HTML primero (CSS), JavaScript se añade AL FINAL
        $html = "<style>{$css}</style>\n";

        /**
         * EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense
         * El anuncio usa tamaño fijo (160xHeight) centrado en el container responsive.
         * Ref: https://support.google.com/adsense/answer/9274516
         */

        // Rail izquierdo
        if ($leftEnabled) {
            $html .= sprintf(
                '<div class="roi-rail-ad roi-rail-ad-left">
                    <ins class="adsbygoogle" style="display:inline-block;width:160px;height:%dpx"
                         data-ad-client="%s" data-ad-slot="%s"></ins>
                    <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
                </div>',
                $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
            );
        }

        // Rail derecho
        if ($rightEnabled) {
            $html .= sprintf(
                '<div class="roi-rail-ad roi-rail-ad-right">
                    <ins class="adsbygoogle" style="display:inline-block;width:160px;height:%dpx"
                         data-ad-client="%s" data-ad-slot="%s"></ins>
                    <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
                </div>',
                $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
            );
        }

        // JavaScript para posicionamiento inteligente de Rail Ads
        // IMPORTANTE: Se añade DESPUES de los divs para garantizar que existan en el DOM
        $html .= "
        <script id=\"roi-rail-ads-positioning\">
        (function() {
            'use strict';

            // Configuracion
            var CONFIG = {
                defaultTop: {$topOffset},
                gap: 30,
                maxTopPercent: 0.45,
                retryDelay: 100,
                maxRetries: 10
            };

            var retryCount = 0;

            function initRailAds() {
                var railAds = document.querySelectorAll('.roi-rail-ad');

                // Si no hay rails, reintentar (puede que el DOM no este listo)
                if (!railAds.length) {
                    if (retryCount < CONFIG.maxRetries) {
                        retryCount++;
                        setTimeout(initRailAds, CONFIG.retryDelay);
                    }
                    return;
                }

                // Selectores especificos del tema ROI
                var navbar = document.querySelector('nav.navbar');
                var hero = document.querySelector('.hero-section, .roi-hero, [class*=\"hero\"]');
                var featuredImage = document.querySelector('.featured-image-container, .post-thumbnail, .entry-image');
                var footer = document.querySelector('footer, .site-footer, #footer, [role=\"contentinfo\"]');

                function getNavbarHeight() {
                    if (navbar) {
                        var style = window.getComputedStyle(navbar);
                        if (style.position === 'fixed' || style.position === 'sticky') {
                            return navbar.offsetHeight || 0;
                        }
                    }
                    return 0;
                }

                function adjustRailPosition() {
                    var navHeight = getNavbarHeight();
                    var newTop = CONFIG.defaultTop;
                    var shouldHide = false;

                    // Detectar si el footer esta visible y los rails lo tocarian
                    if (footer) {
                        var footerRect = footer.getBoundingClientRect();
                        var railHeight = railAds[0] ? railAds[0].offsetHeight : {$height};

                        // Si el footer esta en la pantalla y el rail lo tocaria, ocultar
                        if (footerRect.top < window.innerHeight && footerRect.top < (newTop + railHeight + 50)) {
                            shouldHide = true;
                        }
                    }

                    // Buscar el elemento mas bajo visible en pantalla
                    var elementsToCheck = [hero, featuredImage].filter(Boolean);

                    if (elementsToCheck.length > 0) {
                        var lowestBottom = 0;

                        elementsToCheck.forEach(function(el) {
                            if (el) {
                                var rect = el.getBoundingClientRect();
                                // Solo considerar si el elemento esta visible (bottom > 0)
                                if (rect.bottom > 0 && rect.top < window.innerHeight) {
                                    lowestBottom = Math.max(lowestBottom, rect.bottom);
                                }
                            }
                        });

                        // Si hay un elemento visible, posicionar debajo de el
                        if (lowestBottom > navHeight) {
                            newTop = lowestBottom + CONFIG.gap;
                        } else {
                            // Si no hay hero visible, usar navbar + gap o default
                            newTop = Math.max(navHeight + CONFIG.gap, CONFIG.defaultTop);
                        }
                    }

                    // Limitar el top maximo
                    var maxTop = window.innerHeight * CONFIG.maxTopPercent;
                    newTop = Math.min(newTop, maxTop);

                    // Asegurar minimo respetando navbar
                    newTop = Math.max(newTop, navHeight + CONFIG.gap);

                    // Re-verificar colision con footer con la nueva posicion
                    if (footer && !shouldHide) {
                        var footerRect = footer.getBoundingClientRect();
                        var railHeight = railAds[0] ? railAds[0].offsetHeight : {$height};
                        if (footerRect.top < (newTop + railHeight + 30)) {
                            shouldHide = true;
                        }
                    }

                    // Aplicar posicion y visibilidad a todos los rails
                    for (var i = 0; i < railAds.length; i++) {
                        railAds[i].style.top = Math.round(newTop) + 'px';
                        railAds[i].style.opacity = shouldHide ? '0' : '1';
                        railAds[i].style.pointerEvents = shouldHide ? 'none' : 'auto';
                    }
                }

                // Throttle para scroll
                var ticking = false;
                function onScroll() {
                    if (!ticking) {
                        requestAnimationFrame(function() {
                            adjustRailPosition();
                            ticking = false;
                        });
                        ticking = true;
                    }
                }

                // Event listeners
                window.addEventListener('scroll', onScroll, { passive: true });
                window.addEventListener('resize', function() {
                    adjustRailPosition();
                }, { passive: true });

                // Ejecutar inmediatamente
                adjustRailPosition();

                // Ejecutar varias veces para asegurar que las imagenes cargaron
                setTimeout(adjustRailPosition, 200);
                setTimeout(adjustRailPosition, 500);
                setTimeout(adjustRailPosition, 1000);

                // Tambien cuando las imagenes cargan
                window.addEventListener('load', adjustRailPosition);
            }

            // Iniciar
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', initRailAds);
            } else {
                initRailAds();
            }
        })();
        </script>";

        return $html;
    }

    /**
     * Renderiza Anchor Ads (anuncios fijos en top/bottom)
     *
     * @param array $settings Configuracion desde BD
     * @return string HTML de los anchor ads
     */
    public function renderAnchorAds(array $settings): string
    {
        // Verificar si Anchor Ads estan habilitados
        if (!($settings['visibility']['is_enabled'] ?? false)) {
            return '';
        }
        if (!($settings['anchor_ads']['anchor_enabled'] ?? false)) {
            return '';
        }

        $publisherId = esc_attr($settings['content']['publisher_id'] ?? '');
        $slotId = $settings['content']['slot_auto'] ?? '';

        if (empty($publisherId) || empty($slotId)) {
            return '';
        }

        // Configuracion de anchor
        $anchorConfig = $settings['anchor_ads'] ?? [];
        $position = $anchorConfig['anchor_position'] ?? 'bottom';
        $height = (int)($anchorConfig['anchor_height'] ?? 90);
        $showMobile = ($anchorConfig['anchor_show_on_mobile'] ?? true) === true;
        $showWide = ($anchorConfig['anchor_show_on_wide_screens'] ?? false) === true;
        $collapsible = ($anchorConfig['anchor_collapsible_enabled'] ?? true) === true;
        $collapsedHeight = (int)($anchorConfig['anchor_collapsed_height'] ?? 24);
        $collapseText = esc_html($anchorConfig['anchor_collapse_button_text'] ?? 'Ver anuncio');
        $closePosition = $anchorConfig['anchor_close_position'] ?? 'right';
        $rememberState = ($anchorConfig['anchor_remember_state'] ?? true) === true;
        $rememberDuration = $anchorConfig['anchor_remember_duration'] ?? 'session';

        $delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;
        $scriptType = $delayEnabled ? 'text/plain' : 'text/javascript';
        $dataAttr = $delayEnabled ? ' data-adsense-push' : '';

        // === CSS via CSSGenerator ===
        $cssRules = [];

        // Base anchor styles - FUERA DE PANTALLA por defecto (NO usar visibility:hidden)
        // Usamos transform para mover fuera de la pantalla, asi AdSense puede medir el slot
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad', [
            'position' => 'fixed',
            'left' => '0',
            'right' => '0',
            'z-index' => '9999',
            'background' => '#f8f9fa',
            'border-color' => '#dee2e6',
            'box-shadow' => '0 -2px 10px rgba(0,0,0,0.1)',
            'transition' => 'height 0.3s ease, transform 0.3s ease',
            'display' => 'flex',
            'align-items' => 'center',
            'justify-content' => 'center',
        ]);

        // Anchor TOP: fuera de pantalla hacia arriba, visible cuando se carga
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad-top', [
            'top' => '0',
            'border-bottom-width' => '1px',
            'border-bottom-style' => 'solid',
            'transform' => 'translateY(-100%)',
        ]);

        // Anchor BOTTOM: fuera de pantalla hacia abajo, visible cuando se carga
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad-bottom', [
            'bottom' => '0',
            'border-top-width' => '1px',
            'border-top-style' => 'solid',
            'transform' => 'translateY(100%)',
        ]);

        // Mostrar anchor cuando AdSense llena el slot (desliza a posicion visible)
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.ad-loaded', [
            'transform' => 'translateY(0)',
        ]);

        // Controls container
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-controls', [
            'position' => 'absolute',
            'top' => '4px',
            'display' => 'flex',
            'gap' => '4px',
            'z-index' => '10',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-controls-left', ['left' => '8px']);
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-controls-right', ['right' => '8px']);
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-controls-center', ['left' => '50%', 'transform' => 'translateX(-50%)']);

        // CRITICAL: El contenedor del anuncio DEBE tener width 100% para que AdSense pueda calcular el tamaño
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-content', [
            'width' => '100%',
            'display' => 'flex',
            'align-items' => 'center',
            'justify-content' => 'center',
        ]);

        // Buttons
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-btn', [
            'width' => '28px',
            'height' => '28px',
            'border' => 'none',
            'border-radius' => '4px',
            'background' => 'rgba(0,0,0,0.1)',
            'color' => '#333',
            'cursor' => 'pointer',
            'font-size' => '14px',
            'display' => 'flex',
            'align-items' => 'center',
            'justify-content' => 'center',
            'transition' => 'background 0.2s',
        ]);

        // Collapsed state
        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.collapsed', [
            'height' => $collapsedHeight . 'px !important',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.collapsed .roi-anchor-content', [
            'display' => 'none',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-expand-bar', [
            'display' => 'none',
            'width' => '100%',
            'height' => '100%',
            'background' => '#e9ecef',
            'border' => 'none',
            'cursor' => 'pointer',
            'font-size' => '12px',
            'color' => '#495057',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.collapsed .roi-anchor-expand-bar', [
            'display' => 'flex',
            'align-items' => 'center',
            'justify-content' => 'center',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-anchor-ad.hidden', [
            'display' => 'none !important',
        ]);

        // Media query para visibilidad
        if (!$showMobile && $showWide) {
            $cssRules[] = "@media (max-width: 999px) { .roi-anchor-ad { display: none !important; } }";
        } elseif ($showMobile && !$showWide) {
            $cssRules[] = "@media (min-width: 1000px) { .roi-anchor-ad { display: none !important; } }";
        } elseif (!$showMobile && !$showWide) {
            $cssRules[] = ".roi-anchor-ad { display: none !important; }";
        }

        $css = implode("\n", $cssRules);
        $html = "<style id=\"roi-anchor-ads-css\">{$css}</style>\n";

        // Renderizar anchor(s)
        $controlsClass = 'roi-anchor-controls roi-anchor-controls-' . esc_attr($closePosition);

        if ($position === 'top' || $position === 'both') {
            $html .= $this->buildAnchorHTML('top', $height, $publisherId, $slotId, $scriptType, $dataAttr, $controlsClass, $collapsible, $collapseText);
        }

        if ($position === 'bottom' || $position === 'both') {
            $html .= $this->buildAnchorHTML('bottom', $height, $publisherId, $slotId, $scriptType, $dataAttr, $controlsClass, $collapsible, $collapseText);
        }

        // Config para JavaScript (data attributes en lugar de inline JS)
        $jsConfig = json_encode([
            'rememberState' => $rememberState,
            'rememberDuration' => $rememberDuration,
            'collapsible' => $collapsible,
        ]);

        $html .= '<script id="roi-anchor-config" type="application/json">' . $jsConfig . '</script>';

        return $html;
    }

    /**
     * Genera HTML para un anchor individual
     */
    private function buildAnchorHTML(
        string $pos,
        int $height,
        string $client,
        string $slot,
        string $scriptType,
        string $dataAttr,
        string $controlsClass,
        bool $collapsible,
        string $collapseText
    ): string {
        $posClass = 'roi-anchor-ad-' . $pos;

        $collapseBtn = $collapsible
            ? '<button class="roi-anchor-btn" data-action="collapse" title="Minimizar"><i class="bi bi-dash"></i></button>'
            : '';

        return sprintf(
            '<div class="roi-anchor-ad %s" data-position="%s" style="height:%dpx;">
                <div class="%s">
                    %s
                    <button class="roi-anchor-btn" data-action="close" title="Cerrar"><i class="bi bi-x"></i></button>
                </div>
                <div class="roi-anchor-content">
                    <ins class="adsbygoogle" style="display:block;width:100%%;height:%dpx"
                         data-ad-client="%s" data-ad-slot="%s"
                         data-ad-format="auto" data-full-width-responsive="true"></ins>
                    <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
                </div>
                <button class="roi-anchor-expand-bar" data-action="expand">
                    <i class="bi bi-plus-circle me-1"></i> %s
                </button>
            </div>',
            esc_attr($posClass),
            esc_attr($pos),
            $height,
            esc_attr($controlsClass),
            $collapseBtn,
            $height - 10,
            esc_attr($client),
            esc_attr($slot),
            $scriptType,
            $dataAttr,
            esc_html($collapseText)
        );
    }

    /**
     * Renderiza Vignette Ad (pantalla completa)
     *
     * @param array $settings Configuracion desde BD
     * @return string HTML del vignette ad
     */
    public function renderVignetteAd(array $settings): string
    {
        // Verificar si Vignette Ads estan habilitados
        if (!($settings['visibility']['is_enabled'] ?? false)) {
            return '';
        }
        if (!($settings['vignette_ads']['vignette_enabled'] ?? false)) {
            return '';
        }

        $publisherId = esc_attr($settings['content']['publisher_id'] ?? '');
        $slotId = $settings['content']['slot_display'] ?? $settings['content']['slot_auto'] ?? '';

        if (empty($publisherId) || empty($slotId)) {
            return '';
        }

        // Configuracion de vignette
        $vignetteConfig = $settings['vignette_ads'] ?? [];
        $trigger = $vignetteConfig['vignette_trigger'] ?? 'pageview';
        $triggerDelay = (int)($vignetteConfig['vignette_trigger_delay'] ?? 5);
        $showMobile = ($vignetteConfig['vignette_show_on_mobile'] ?? true) === true;
        $showDesktop = ($vignetteConfig['vignette_show_on_desktop'] ?? true) === true;
        $size = $vignetteConfig['vignette_size'] ?? '300x250';
        $overlayOpacity = (float)($vignetteConfig['vignette_overlay_opacity'] ?? 0.7);
        $closeDelay = (int)($vignetteConfig['vignette_close_button_delay'] ?? 0);
        $reshowEnabled = ($vignetteConfig['vignette_reshow_enabled'] ?? true) === true;
        $reshowTime = (int)($vignetteConfig['vignette_reshow_time'] ?? 5);
        $maxPerSession = $vignetteConfig['vignette_max_per_session'] ?? '3';
        $maxPerPage = $vignetteConfig['vignette_max_per_page'] ?? '1';

        // Calcular dimensiones
        list($adWidth, $adHeight) = $this->parseVignetteSize($size);

        $delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;
        $scriptType = $delayEnabled ? 'text/plain' : 'text/javascript';
        $dataAttr = $delayEnabled ? ' data-adsense-push' : '';

        // === CSS via CSSGenerator ===
        $cssRules = [];

        $cssRules[] = $this->cssGenerator->generate('.roi-vignette-overlay', [
            'position' => 'fixed',
            'top' => '0',
            'left' => '0',
            'right' => '0',
            'bottom' => '0',
            'background' => 'rgba(0,0,0,' . $overlayOpacity . ')',
            'z-index' => '99999',
            'display' => 'none',
            'align-items' => 'center',
            'justify-content' => 'center',
            'opacity' => '0',
            'transition' => 'opacity 0.3s ease',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-vignette-overlay.active', [
            'display' => 'flex',
            'opacity' => '1',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-vignette-modal', [
            'position' => 'relative',
            'background' => '#fff',
            'border-radius' => '8px',
            'padding' => '20px',
            'box-shadow' => '0 10px 40px rgba(0,0,0,0.3)',
            'max-width' => '95vw',
            'max-height' => '95vh',
            'overflow' => 'auto',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-vignette-close', [
            'position' => 'absolute',
            'top' => '-12px',
            'right' => '-12px',
            'width' => '32px',
            'height' => '32px',
            'border' => 'none',
            'border-radius' => '50%',
            'background' => '#dc3545',
            'color' => '#fff',
            'cursor' => 'pointer',
            'font-size' => '18px',
            'display' => 'flex',
            'align-items' => 'center',
            'justify-content' => 'center',
            'box-shadow' => '0 2px 8px rgba(0,0,0,0.2)',
            'transition' => 'transform 0.2s, opacity 0.3s',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-vignette-close.delayed', [
            'opacity' => '0',
            'pointer-events' => 'none',
        ]);

        $cssRules[] = $this->cssGenerator->generate('.roi-vignette-close:not(.delayed)', [
            'opacity' => '1',
            'pointer-events' => 'auto',
        ]);

        // Media query para visibilidad
        if (!$showMobile && $showDesktop) {
            $cssRules[] = "@media (max-width: 991px) { .roi-vignette-overlay { display: none !important; } }";
        } elseif ($showMobile && !$showDesktop) {
            $cssRules[] = "@media (min-width: 992px) { .roi-vignette-overlay { display: none !important; } }";
        } elseif (!$showMobile && !$showDesktop) {
            $cssRules[] = ".roi-vignette-overlay { display: none !important; }";
        }

        $css = implode("\n", $cssRules);
        $html = "<style id=\"roi-vignette-css\">{$css}</style>\n";

        // Determinar estilo de anuncio segun tamano
        if ($size === 'auto' || $size === 'responsive') {
            $adStyle = 'display:block;min-width:300px;min-height:250px';
            $adFormat = ' data-ad-format="auto" data-full-width-responsive="true"';
        } else {
            $adStyle = sprintf('display:inline-block;width:%dpx;height:%dpx', $adWidth, $adHeight);
            $adFormat = '';
        }

        // Sin boton de cerrar - el usuario cierra haciendo clic fuera del modal
        $html .= sprintf(
            '<div id="roi-vignette-overlay" class="roi-vignette-overlay">
                <div class="roi-vignette-modal">
                    <ins class="adsbygoogle" style="%s"
                         data-ad-client="%s" data-ad-slot="%s"%s></ins>
                    <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
                </div>
            </div>',
            $adStyle,
            esc_attr($publisherId),
            esc_attr($slotId),
            $adFormat,
            $scriptType,
            $dataAttr
        );

        // Config para JavaScript
        $jsConfig = json_encode([
            'trigger' => $trigger,
            'triggerDelay' => $triggerDelay,
            'closeDelay' => $closeDelay,
            'reshowEnabled' => $reshowEnabled,
            'reshowTime' => $reshowTime,
            'maxPerSession' => $maxPerSession,
            'maxPerPage' => $maxPerPage,
        ]);

        $html .= '<script id="roi-vignette-config" type="application/json">' . $jsConfig . '</script>';

        return $html;
    }

    /**
     * Parsea el tamano del vignette
     */
    private function parseVignetteSize(string $size): array
    {
        return match($size) {
            '1280x720' => [1280, 720],
            '960x540' => [960, 540],
            '854x480' => [854, 480],
            '800x450' => [800, 450],
            '640x360' => [640, 360],
            '560x315' => [560, 315],
            '336x280' => [336, 280],
            '300x250' => [300, 250],
            'auto', 'responsive' => [0, 0], // Tamaños dinamicos
            default => [960, 540], // Default a tamaño video qHD
        };
    }
}
