<?php
declare(strict_types=1);

namespace ROITheme\Shared\Infrastructure\Ui;

use ROITheme\Shared\Domain\Entities\Component;
use ROITheme\Shared\Domain\Contracts\FormBuilderInterface;

/**
 * TopNotificationBarFormBuilder - Construye formulario de configuración
 *
 * RESPONSABILIDAD: Generar formulario HTML del admin para Top Notification Bar
 *
 * CARACTERÍSTICAS:
 * - 3 secciones: Visibilidad, Contenido, Estilos
 * - 19 campos configurables
 * - Lógica condicional (data-conditional-field)
 * - WordPress Media Library integration
 * - Vista previa en tiempo real
 *
 * @package ROITheme\Shared\Infrastructure\Ui
 */
final class TopNotificationBarFormBuilder implements FormBuilderInterface
{
    public function build(Component $component): string
    {
        $data = $component->getData();
        $componentId = $component->getName();

        $html = '<div class="roi-form-builder roi-top-notification-bar-form">';

        // Sección de Visibilidad
        $html .= $this->buildVisibilitySection($data, $componentId);

        // Sección de Contenido
        $html .= $this->buildContentSection($data, $componentId);

        // Sección de Estilos
        $html .= $this->buildStylesSection($data, $componentId);

        // Vista previa
        $html .= $this->buildPreviewSection($data);

        $html .= '</div>';

        // Agregar scripts de formulario
        $html .= $this->buildFormScripts($componentId);

        return $html;
    }

    private function buildVisibilitySection(array $data, string $componentId): string
    {
        $html = '<div class="roi-form-section" data-section="visibility">';
        $html .= '<h3 class="roi-form-section-title">Visibilidad</h3>';
        $html .= '<div class="roi-form-section-content">';

        // Is Enabled
        $isEnabled = $data['visibility']['is_enabled'] ?? true;
        $html .= $this->buildToggle(
            'is_enabled',
            'Mostrar barra de notificación',
            $isEnabled,
            $componentId,
            'Activa o desactiva la barra de notificación superior'
        );

        // Show On Pages
        $showOn = $data['visibility']['show_on_pages'] ?? 'all';
        $html .= $this->buildSelect(
            'show_on_pages',
            'Mostrar en',
            $showOn,
            [
                'all' => 'Todas las páginas',
                'home' => 'Solo página de inicio',
                'posts' => 'Solo posts individuales',
                'pages' => 'Solo páginas',
                'custom' => 'Páginas específicas'
            ],
            $componentId,
            'Define en qué páginas se mostrará la barra'
        );

        // Custom Page IDs
        $customPageIds = $data['visibility']['custom_page_ids'] ?? '';
        $html .= $this->buildTextField(
            'custom_page_ids',
            'IDs de páginas específicas',
            $customPageIds,
            $componentId,
            'IDs de páginas separados por comas',
            'Ej: 1,5,10',
            ['data-conditional-field' => 'show_on_pages', 'data-conditional-value' => 'custom']
        );

        // Hide On Mobile
        $hideOnMobile = $data['visibility']['hide_on_mobile'] ?? false;
        $html .= $this->buildToggle(
            'hide_on_mobile',
            'Ocultar en dispositivos móviles',
            $hideOnMobile,
            $componentId,
            'Oculta la barra en pantallas menores a 768px'
        );

        // Is Dismissible
        $isDismissible = $data['visibility']['is_dismissible'] ?? false;
        $html .= $this->buildToggle(
            'is_dismissible',
            'Permitir cerrar',
            $isDismissible,
            $componentId,
            'Agrega botón X para que el usuario pueda cerrar la barra'
        );

        // Dismissible Cookie Days
        $cookieDays = $data['visibility']['dismissible_cookie_days'] ?? 7;
        $html .= $this->buildNumberField(
            'dismissible_cookie_days',
            'Días antes de volver a mostrar',
            $cookieDays,
            $componentId,
            'Días que permanece oculta después de cerrarla',
            1,
            365,
            ['data-conditional-field' => 'is_dismissible', 'data-conditional-value' => 'true']
        );

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

        return $html;
    }

    private function buildContentSection(array $data, string $componentId): string
    {
        $html = '<div class="roi-form-section" data-section="content">';
        $html .= '<h3 class="roi-form-section-title">Contenido</h3>';
        $html .= '<div class="roi-form-section-content">';

        // Icon Type
        $iconType = $data['content']['icon_type'] ?? 'bootstrap';
        $html .= $this->buildSelect(
            'icon_type',
            'Tipo de ícono',
            $iconType,
            [
                'bootstrap' => 'Bootstrap Icons',
                'custom' => 'Imagen personalizada',
                'none' => 'Sin ícono'
            ],
            $componentId,
            'Selecciona el tipo de ícono a mostrar'
        );

        // Bootstrap Icon
        $bootstrapIcon = $data['content']['bootstrap_icon'] ?? 'bi-megaphone-fill';
        $html .= $this->buildTextField(
            'bootstrap_icon',
            'Clase de ícono Bootstrap',
            $bootstrapIcon,
            $componentId,
            'Nombre de la clase del ícono sin el prefijo \'bi\' (ej: megaphone-fill)',
            'Ej: bi-megaphone-fill',
            ['data-conditional-field' => 'icon_type', 'data-conditional-value' => 'bootstrap']
        );

        // Custom Icon URL
        $customIconUrl = $data['content']['custom_icon_url'] ?? '';
        $html .= $this->buildMediaField(
            'custom_icon_url',
            'Imagen personalizada',
            $customIconUrl,
            $componentId,
            'Sube una imagen personalizada (recomendado: PNG 24x24px)',
            ['data-conditional-field' => 'icon_type', 'data-conditional-value' => 'custom']
        );

        // Announcement Label
        $announcementLabel = $data['content']['announcement_label'] ?? 'Nuevo:';
        $html .= $this->buildTextField(
            'announcement_label',
            'Etiqueta del anuncio',
            $announcementLabel,
            $componentId,
            'Texto destacado en negrita antes del mensaje',
            'Ej: Nuevo:, Importante:, Aviso:'
        );

        // Announcement Text
        $announcementText = $data['content']['announcement_text'] ?? 'Accede a más de 200,000 Análisis de Precios Unitarios actualizados para 2025.';
        $html .= $this->buildTextArea(
            'announcement_text',
            'Texto del anuncio',
            $announcementText,
            $componentId,
            'Mensaje principal del anuncio (máximo 200 caracteres)',
            3
        );

        // Link Enabled
        $linkEnabled = $data['content']['link_enabled'] ?? true;
        $html .= $this->buildToggle(
            'link_enabled',
            'Mostrar enlace',
            $linkEnabled,
            $componentId,
            'Activa o desactiva el enlace de acción'
        );

        // Link Text
        $linkText = $data['content']['link_text'] ?? 'Ver Catálogo';
        $html .= $this->buildTextField(
            'link_text',
            'Texto del enlace',
            $linkText,
            $componentId,
            'Texto del enlace de acción',
            '',
            ['data-conditional-field' => 'link_enabled', 'data-conditional-value' => 'true']
        );

        // Link URL
        $linkUrl = $data['content']['link_url'] ?? '#';
        $html .= $this->buildUrlField(
            'link_url',
            'URL del enlace',
            $linkUrl,
            $componentId,
            'URL de destino del enlace',
            'https://',
            ['data-conditional-field' => 'link_enabled', 'data-conditional-value' => 'true']
        );

        // Link Target
        $linkTarget = $data['content']['link_target'] ?? '_self';
        $html .= $this->buildSelect(
            'link_target',
            'Abrir enlace en',
            $linkTarget,
            [
                '_self' => 'Misma ventana',
                '_blank' => 'Nueva ventana'
            ],
            $componentId,
            'Define cómo se abrirá el enlace',
            ['data-conditional-field' => 'link_enabled', 'data-conditional-value' => 'true']
        );

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

        return $html;
    }

    private function buildStylesSection(array $data, string $componentId): string
    {
        $html = '<div class="roi-form-section" data-section="styles">';
        $html .= '<h3 class="roi-form-section-title">Estilos</h3>';
        $html .= '<div class="roi-form-section-content">';

        // Background Color
        $bgColor = $data['styles']['background_color'] ?? '#FF8600';
        $html .= $this->buildColorField(
            'background_color',
            'Color de fondo',
            $bgColor,
            $componentId,
            'Color de fondo de la barra (por defecto: orange primary)'
        );

        // Text Color
        $textColor = $data['styles']['text_color'] ?? '#FFFFFF';
        $html .= $this->buildColorField(
            'text_color',
            'Color del texto',
            $textColor,
            $componentId,
            'Color del texto del anuncio'
        );

        // Link Color
        $linkColor = $data['styles']['link_color'] ?? '#FFFFFF';
        $html .= $this->buildColorField(
            'link_color',
            'Color del enlace',
            $linkColor,
            $componentId,
            'Color del enlace de acción'
        );

        // Font Size
        $fontSize = $data['styles']['font_size'] ?? 'small';
        $html .= $this->buildSelect(
            'font_size',
            'Tamaño de fuente',
            $fontSize,
            [
                'extra-small' => 'Muy pequeño (0.75rem)',
                'small' => 'Pequeño (0.875rem)',
                'normal' => 'Normal (1rem)',
                'large' => 'Grande (1.125rem)'
            ],
            $componentId,
            'Tamaño del texto del anuncio'
        );

        // Padding Vertical
        $padding = $data['styles']['padding_vertical'] ?? 'normal';
        $html .= $this->buildSelect(
            'padding_vertical',
            'Padding vertical',
            $padding,
            [
                'compact' => 'Compacto (0.5rem)',
                'normal' => 'Normal (0.75rem)',
                'spacious' => 'Espacioso (1rem)'
            ],
            $componentId,
            'Espaciado vertical interno de la barra'
        );

        // Text Alignment
        $alignment = $data['styles']['text_alignment'] ?? 'center';
        $html .= $this->buildSelect(
            'text_alignment',
            'Alineación del texto',
            $alignment,
            [
                'left' => 'Izquierda',
                'center' => 'Centro',
                'right' => 'Derecha'
            ],
            $componentId,
            'Alineación del contenido de la barra'
        );

        // Animation Enabled
        $animationEnabled = $data['styles']['animation_enabled'] ?? false;
        $html .= $this->buildToggle(
            'animation_enabled',
            'Activar animación',
            $animationEnabled,
            $componentId,
            'Activa animación de entrada al cargar la página'
        );

        // Animation Type
        $animationType = $data['styles']['animation_type'] ?? 'slide-down';
        $html .= $this->buildSelect(
            'animation_type',
            'Tipo de animación',
            $animationType,
            [
                'slide-down' => 'Deslizar desde arriba',
                'fade-in' => 'Aparecer gradualmente'
            ],
            $componentId,
            'Tipo de animación de entrada',
            ['data-conditional-field' => 'animation_enabled', 'data-conditional-value' => 'true']
        );

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

        return $html;
    }

    private function buildPreviewSection(array $data): string
    {
        $html = '<div class="roi-form-section roi-preview-section">';
        $html .= '<h3 class="roi-form-section-title">Vista Previa</h3>';
        $html .= '<div class="roi-form-section-content">';
        $html .= '<div id="roi-component-preview" class="border rounded p-3 bg-light">';
        $html .= '<p class="text-muted">La vista previa se actualizará automáticamente al modificar los campos.</p>';
        $html .= '</div>';
        $html .= '</div>';
        $html .= '</div>';

        return $html;
    }

    private function buildToggle(string $name, string $label, bool $value, string $componentId, string $description = ''): string
    {
        $fieldId = "roi_{$componentId}_{$name}";
        $checked = $value ? 'checked' : '';

        $html = '<div class="roi-form-field roi-form-field-toggle mb-3">';
        $html .= '<div class="form-check form-switch">';
        $html .= sprintf(
            '<input type="checkbox" class="form-check-input" id="%s" name="roi_component[%s][%s]" value="1" %s>',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            $checked
        );
        $html .= sprintf('<label class="form-check-label" for="%s">%s</label>', esc_attr($fieldId), esc_html($label));
        $html .= '</div>';
        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildTextField(string $name, string $label, string $value, string $componentId, string $description = '', string $placeholder = '', array $attrs = []): string
    {
        $fieldId = "roi_{$componentId}_{$name}";

        $html = '<div class="roi-form-field roi-form-field-text mb-3">';
        $html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));

        $attrString = $this->buildAttributesString($attrs);

        $html .= sprintf(
            '<input type="text" class="form-control" id="%s" name="roi_component[%s][%s]" value="%s" placeholder="%s"%s>',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            esc_attr($value),
            esc_attr($placeholder),
            $attrString
        );

        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildTextArea(string $name, string $label, string $value, string $componentId, string $description = '', int $rows = 3, array $attrs = []): string
    {
        $fieldId = "roi_{$componentId}_{$name}";

        $html = '<div class="roi-form-field roi-form-field-textarea mb-3">';
        $html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));

        $attrString = $this->buildAttributesString($attrs);

        $html .= sprintf(
            '<textarea class="form-control" id="%s" name="roi_component[%s][%s]" rows="%d"%s>%s</textarea>',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            $rows,
            $attrString,
            esc_textarea($value)
        );

        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildSelect(string $name, string $label, string $value, array $options, string $componentId, string $description = '', array $attrs = []): string
    {
        $fieldId = "roi_{$componentId}_{$name}";

        $html = '<div class="roi-form-field roi-form-field-select mb-3">';
        $html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));

        $attrString = $this->buildAttributesString($attrs);

        $html .= sprintf(
            '<select class="form-select" id="%s" name="roi_component[%s][%s]"%s>',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            $attrString
        );

        foreach ($options as $optValue => $optLabel) {
            $selected = ($value === $optValue) ? 'selected' : '';
            $html .= sprintf(
                '<option value="%s" %s>%s</option>',
                esc_attr($optValue),
                $selected,
                esc_html($optLabel)
            );
        }

        $html .= '</select>';

        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildNumberField(string $name, string $label, $value, string $componentId, string $description = '', int $min = null, int $max = null, array $attrs = []): string
    {
        $fieldId = "roi_{$componentId}_{$name}";

        $html = '<div class="roi-form-field roi-form-field-number mb-3">';
        $html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));

        $attrs['type'] = 'number';
        if ($min !== null) {
            $attrs['min'] = $min;
        }
        if ($max !== null) {
            $attrs['max'] = $max;
        }

        $attrString = $this->buildAttributesString($attrs);

        $html .= sprintf(
            '<input class="form-control" id="%s" name="roi_component[%s][%s]" value="%s"%s>',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            esc_attr($value),
            $attrString
        );

        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildUrlField(string $name, string $label, string $value, string $componentId, string $description = '', string $placeholder = '', array $attrs = []): string
    {
        $attrs['type'] = 'url';
        return $this->buildTextField($name, $label, $value, $componentId, $description, $placeholder, $attrs);
    }

    private function buildColorField(string $name, string $label, string $value, string $componentId, string $description = ''): string
    {
        $fieldId = "roi_{$componentId}_{$name}";

        $html = '<div class="roi-form-field roi-form-field-color mb-3">';
        $html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
        $html .= '<div class="input-group">';
        $html .= sprintf(
            '<input type="color" class="form-control form-control-color" id="%s" name="roi_component[%s][%s]" value="%s">',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            esc_attr($value)
        );
        $html .= sprintf(
            '<input type="text" class="form-control" value="%s" readonly>',
            esc_attr($value)
        );
        $html .= '</div>';
        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildMediaField(string $name, string $label, string $value, string $componentId, string $description = '', array $attrs = []): string
    {
        $fieldId = "roi_{$componentId}_{$name}";

        $html = '<div class="roi-form-field roi-form-field-media mb-3">';
        $html .= sprintf('<label for="%s" class="form-label">%s</label>', esc_attr($fieldId), esc_html($label));
        $html .= '<div class="input-group">';

        $attrString = $this->buildAttributesString($attrs);

        $html .= sprintf(
            '<input type="text" class="form-control" id="%s" name="roi_component[%s][%s]" value="%s" readonly%s>',
            esc_attr($fieldId),
            esc_attr($componentId),
            esc_attr($name),
            esc_attr($value),
            $attrString
        );
        $html .= sprintf(
            '<button type="button" class="btn btn-primary roi-media-upload-btn" data-target="%s">Seleccionar</button>',
            esc_attr($fieldId)
        );
        $html .= '</div>';

        if (!empty($value)) {
            $html .= sprintf('<div class="mt-2"><img src="%s" alt="Preview" style="max-width: 100px; height: auto;"></div>', esc_url($value));
        }

        if (!empty($description)) {
            $html .= sprintf('<small class="form-text text-muted">%s</small>', esc_html($description));
        }
        $html .= '</div>';

        return $html;
    }

    private function buildAttributesString(array $attrs): string
    {
        $attrString = '';
        foreach ($attrs as $key => $value) {
            $attrString .= sprintf(' %s="%s"', esc_attr($key), esc_attr($value));
        }
        return $attrString;
    }

    private function buildFormScripts(string $componentId): string
    {
        return <<<SCRIPT
<script>
(function($) {
    'use strict';

    $(document).ready(function() {
        // Conditional logic
        $('[data-conditional-field]').each(function() {
            const field = $(this);
            const targetFieldName = field.data('conditional-field');
            const targetValue = field.data('conditional-value');
            const targetField = $('[name*="[' + targetFieldName + ']"]');

            function updateVisibility() {
                let currentValue;
                if (targetField.is(':checkbox')) {
                    currentValue = targetField.is(':checked') ? 'true' : 'false';
                } else {
                    currentValue = targetField.val();
                }

                if (currentValue === targetValue) {
                    field.closest('.roi-form-field').show();
                } else {
                    field.closest('.roi-form-field').hide();
                }
            }

            targetField.on('change', updateVisibility);
            updateVisibility();
        });

        // Media upload
        $('.roi-media-upload-btn').on('click', function(e) {
            e.preventDefault();
            const button = $(this);
            const targetId = button.data('target');
            const targetField = $('#' + targetId);

            const mediaUploader = wp.media({
                title: 'Seleccionar imagen',
                button: { text: 'Usar esta imagen' },
                multiple: false
            });

            mediaUploader.on('select', function() {
                const attachment = mediaUploader.state().get('selection').first().toJSON();
                targetField.val(attachment.url);

                const preview = targetField.closest('.roi-form-field-media').find('img');
                if (preview.length) {
                    preview.attr('src', attachment.url);
                } else {
                    targetField.closest('.input-group').after('<div class="mt-2"><img src="' + attachment.url + '" alt="Preview" style="max-width: 100px; height: auto;"></div>');
                }
            });

            mediaUploader.open();
        });

        // Color picker sync
        $('.form-control-color').on('change', function() {
            $(this).next('input[type="text"]').val($(this).val());
        });

        // Auto-update preview
        $('.roi-form-field input, .roi-form-field select, .roi-form-field textarea').on('change keyup', function() {
            updatePreview();
        });

        function updatePreview() {
            // Aquí iría la lógica para actualizar la vista previa en tiempo real
            console.log('Preview updated');
        }
    });
})(jQuery);
</script>
SCRIPT;
    }

    public function supports(string $componentType): bool
    {
        return $componentType === 'top-notification-bar';
    }
}
