<?php
declare(strict_types=1);

namespace ROITheme\Public\HeroSection\Infrastructure\Ui;

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

/**
 * HeroSectionRenderer - Renderiza la sección hero con badges y título
 *
 * RESPONSABILIDAD: Generar HTML de la sección hero
 *
 * CARACTERÍSTICAS:
 * - Badges de categorías con múltiples fuentes de datos
 * - Título H1 con gradiente opcional
 * - Múltiples tipos de fondo (color, gradiente, imagen)
 * - Lógica condicional de visibilidad por tipo de página
 *
 * @package ROITheme\Public\HeroSection\Presentation
 */
final class HeroSectionRenderer implements RendererInterface
{
    public function render(Component $component): string
    {
        $data = $component->getData();

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

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

        $classes = $this->buildSectionClasses($data);
        $styles = $this->buildInlineStyles($data);

        $html = sprintf(
            '<div class="%s"%s>',
            esc_attr($classes),
            $styles ? ' style="' . esc_attr($styles) . '"' : ''
        );

        $html .= '<div class="container">';

        // Categories badges
        if ($this->shouldShowCategories($data)) {
            $html .= $this->buildCategoriesBadges($data);
        }

        // Title
        $html .= $this->buildTitle($data);

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

        // Custom styles
        $html .= $this->buildCustomStyles($data);

        return $html;
    }

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

    private function shouldShowOnCurrentPage(array $data): bool
    {
        $showOn = $data['visibility']['show_on_pages'] ?? 'posts';

        switch ($showOn) {
            case 'all':
                return true;

            case 'home':
                return is_front_page();

            case 'posts':
                return is_single() && get_post_type() === 'post';

            case 'pages':
                return is_page();

            case 'custom':
                $postTypes = $data['visibility']['custom_post_types'] ?? '';
                $allowedTypes = array_map('trim', explode(',', $postTypes));
                return in_array(get_post_type(), $allowedTypes, true);

            default:
                return true;
        }
    }

    private function shouldShowCategories(array $data): bool
    {
        return isset($data['categories']['show_categories']) &&
               $data['categories']['show_categories'] === true;
    }

    private function buildSectionClasses(array $data): string
    {
        $classes = ['container-fluid', 'hero-title'];

        $paddingClass = $this->getPaddingClass($data['styles']['padding_vertical'] ?? 'normal');
        $classes[] = $paddingClass;

        $marginClass = $this->getMarginClass($data['styles']['margin_bottom'] ?? 'normal');
        if ($marginClass) {
            $classes[] = $marginClass;
        }

        return implode(' ', $classes);
    }

    private function getPaddingClass(string $padding): string
    {
        $paddings = [
            'compact' => 'py-3',
            'normal' => 'py-5',
            'spacious' => 'py-6',
            'extra-spacious' => 'py-7'
        ];

        return $paddings[$padding] ?? 'py-5';
    }

    private function getMarginClass(string $margin): string
    {
        $margins = [
            'none' => '',
            'small' => 'mb-2',
            'normal' => 'mb-4',
            'large' => 'mb-5'
        ];

        return $margins[$margin] ?? 'mb-4';
    }

    private function buildInlineStyles(array $data): string
    {
        $styles = [];
        $backgroundType = $data['styles']['background_type'] ?? 'gradient';

        switch ($backgroundType) {
            case 'color':
                $bgColor = $data['styles']['background_color'] ?? '#1e3a5f';
                $styles[] = "background-color: {$bgColor}";
                break;

            case 'gradient':
                $startColor = $data['styles']['gradient_start_color'] ?? '#1e3a5f';
                $endColor = $data['styles']['gradient_end_color'] ?? '#2c5282';
                $angle = $data['styles']['gradient_angle'] ?? 135;
                $styles[] = "background: linear-gradient({$angle}deg, {$startColor}, {$endColor})";
                break;

            case 'image':
                $imageUrl = $data['styles']['background_image_url'] ?? '';
                if (!empty($imageUrl)) {
                    $styles[] = "background-image: url('" . esc_url($imageUrl) . "')";
                    $styles[] = "background-size: cover";
                    $styles[] = "background-position: center";
                    $styles[] = "background-repeat: no-repeat";

                    if (isset($data['styles']['background_overlay']) && $data['styles']['background_overlay']) {
                        $opacity = ($data['styles']['overlay_opacity'] ?? 60) / 100;
                        $styles[] = "position: relative";
                    }
                }
                break;
        }

        // Text color
        if (!empty($data['styles']['text_color'])) {
            $styles[] = 'color: ' . $data['styles']['text_color'];
        }

        return implode('; ', $styles);
    }

    private function buildCategoriesBadges(array $data): string
    {
        $categories = $this->getCategories($data);

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

        $maxCategories = $data['categories']['max_categories'] ?? 5;
        $categories = array_slice($categories, 0, $maxCategories);

        $alignment = $data['categories']['categories_alignment'] ?? 'center';
        $alignmentClasses = [
            'left' => 'justify-content-start',
            'center' => 'justify-content-center',
            'right' => 'justify-content-end'
        ];
        $alignmentClass = $alignmentClasses[$alignment] ?? 'justify-content-center';

        $icon = $data['categories']['category_icon'] ?? 'bi-folder-fill';
        if (strpos($icon, 'bi-') !== 0) {
            $icon = 'bi-' . $icon;
        }

        $html = sprintf('<div class="mb-3 d-flex %s">', esc_attr($alignmentClass));
        $html .= '<div class="d-flex gap-2 flex-wrap justify-content-center">';

        foreach ($categories as $category) {
            $html .= sprintf(
                '<a href="%s" class="category-badge category-badge-hero"><i class="bi %s me-1"></i>%s</a>',
                esc_url($category['url']),
                esc_attr($icon),
                esc_html($category['name'])
            );
        }

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

        return $html;
    }

    private function getCategories(array $data): array
    {
        $source = $data['categories']['categories_source'] ?? 'post_categories';

        switch ($source) {
            case 'post_categories':
                return $this->getPostCategories();

            case 'post_tags':
                return $this->getPostTags();

            case 'custom_taxonomy':
                $taxonomy = $data['categories']['custom_taxonomy_name'] ?? '';
                return $this->getCustomTaxonomyTerms($taxonomy);

            case 'custom_list':
                $list = $data['categories']['custom_categories_list'] ?? '';
                return $this->parseCustomCategoriesList($list);

            default:
                return [];
        }
    }

    private function getPostCategories(): array
    {
        $categories = get_the_category();
        if (empty($categories)) {
            return [];
        }

        $result = [];
        foreach ($categories as $category) {
            $result[] = [
                'name' => $category->name,
                'url' => get_category_link($category->term_id)
            ];
        }

        return $result;
    }

    private function getPostTags(): array
    {
        $tags = get_the_tags();
        if (empty($tags)) {
            return [];
        }

        $result = [];
        foreach ($tags as $tag) {
            $result[] = [
                'name' => $tag->name,
                'url' => get_tag_link($tag->term_id)
            ];
        }

        return $result;
    }

    private function getCustomTaxonomyTerms(string $taxonomy): array
    {
        if (empty($taxonomy)) {
            return [];
        }

        $terms = get_the_terms(get_the_ID(), $taxonomy);
        if (empty($terms) || is_wp_error($terms)) {
            return [];
        }

        $result = [];
        foreach ($terms as $term) {
            $result[] = [
                'name' => $term->name,
                'url' => get_term_link($term)
            ];
        }

        return $result;
    }

    private function parseCustomCategoriesList(string $list): array
    {
        if (empty($list)) {
            return [];
        }

        $lines = explode("\n", $list);
        $result = [];

        foreach ($lines as $line) {
            $line = trim($line);
            if (empty($line)) {
                continue;
            }

            $parts = explode('|', $line);
            if (count($parts) >= 2) {
                $result[] = [
                    'name' => trim($parts[0]),
                    'url' => trim($parts[1])
                ];
            }
        }

        return $result;
    }

    private function buildTitle(array $data): string
    {
        $titleText = $this->getTitleText($data);

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

        $titleTag = $data['title']['title_tag'] ?? 'h1';
        $titleClasses = $data['title']['title_classes'] ?? 'display-5 fw-bold';
        $alignment = $data['title']['title_alignment'] ?? 'center';

        $alignmentClasses = [
            'left' => 'text-start',
            'center' => 'text-center',
            'right' => 'text-end'
        ];
        $alignmentClass = $alignmentClasses[$alignment] ?? 'text-center';

        $classes = trim($titleClasses . ' ' . $alignmentClass);

        $titleStyle = '';
        if (isset($data['title']['enable_gradient']) && $data['title']['enable_gradient']) {
            $titleStyle = $this->buildGradientStyle($data);
            $classes .= ' roi-gradient-text';
        }

        return sprintf(
            '<%s class="%s"%s>%s</%s>',
            esc_attr($titleTag),
            esc_attr($classes),
            $titleStyle ? ' style="' . esc_attr($titleStyle) . '"' : '',
            esc_html($titleText),
            esc_attr($titleTag)
        );
    }

    private function getTitleText(array $data): string
    {
        $source = $data['title']['title_source'] ?? 'post_title';

        switch ($source) {
            case 'post_title':
                return get_the_title();

            case 'custom_field':
                $fieldName = $data['title']['custom_field_name'] ?? '';
                if (!empty($fieldName)) {
                    $value = get_post_meta(get_the_ID(), $fieldName, true);
                    return is_string($value) ? $value : '';
                }
                return '';

            case 'custom_text':
                return $data['title']['custom_text'] ?? '';

            default:
                return get_the_title();
        }
    }

    private function buildGradientStyle(array $data): string
    {
        $startColor = $data['title']['gradient_color_start'] ?? '#1e3a5f';
        $endColor = $data['title']['gradient_color_end'] ?? '#FF8600';
        $direction = $data['title']['gradient_direction'] ?? 'to-right';

        $directions = [
            'to-right' => 'to right',
            'to-left' => 'to left',
            'to-bottom' => 'to bottom',
            'to-top' => 'to top',
            'diagonal' => '135deg'
        ];

        $gradientDirection = $directions[$direction] ?? 'to right';

        return "background: linear-gradient({$gradientDirection}, {$startColor}, {$endColor}); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;";
    }

    private function buildCustomStyles(array $data): string
    {
        $badgeBg = $data['styles']['category_badge_background'] ?? 'rgba(255, 255, 255, 0.2)';
        $badgeTextColor = $data['styles']['category_badge_text_color'] ?? '#FFFFFF';
        $badgeBlur = isset($data['styles']['category_badge_blur']) && $data['styles']['category_badge_blur'];

        $blurStyle = $badgeBlur ? 'backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);' : '';

        $overlayStyle = '';
        if (($data['styles']['background_type'] ?? '') === 'image' &&
            isset($data['styles']['background_overlay']) &&
            $data['styles']['background_overlay']) {
            $opacity = ($data['styles']['overlay_opacity'] ?? 60) / 100;
            $overlayStyle = <<<CSS
.hero-title::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, {$opacity});
    z-index: 0;
}
.hero-title > .container {
    position: relative;
    z-index: 1;
}
CSS;
        }

        return <<<STYLES
<style>
.category-badge-hero {
    background-color: {$badgeBg};
    color: {$badgeTextColor};
    padding: 0.5rem 1rem;
    border-radius: 2rem;
    text-decoration: none;
    font-size: 0.875rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    transition: all 0.3s ease;
    {$blurStyle}
}
.category-badge-hero:hover {
    background-color: rgba(255, 134, 0, 0.3);
    color: {$badgeTextColor};
    transform: translateY(-2px);
}
.roi-gradient-text {
    display: inline-block;
}
{$overlayStyle}
</style>
STYLES;
    }

    public function supports(string $componentType): bool
    {
        return $componentType === 'hero-section';
    }
}
