<?php

namespace XZD\AI\V5\Theme;

use XZD\AI\V5\Core\Config;

/**
 * 标签美化管理器 V3 — 简约可靠
 *
 * 设计原则（崩溃教训总结）：
 * - 绝不修改 display / position / overflow / white-space
 * - 只改颜色、边框、圆角、阴影、字号
 * - JS统一在标签链接上打类名：.xzd-tag-themed + .xzd-tag-{scene}
 * - Hash替换：JS包裹 # 进 span → CSS ::before 渲染图形
 */
class TagStyleManager
{
    private static ?self $instance = null;

    public static function instance(): self
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function init(): void
    {
        if (is_admin()) return;
        if (get_template() !== 'zibll') return;

        $s = $this->getSettings();
        if (empty($s['enabled'])) return;

        add_action('wp_head', [$this, 'injectCSS'], 99);
        add_action('wp_print_footer_scripts', [$this, 'injectJS'], 20);
    }

    // ═══════════ 配置 ═══════════

    public function getSettings(): array
    {
        $saved = Config::instance()->get('tag_style', []);
        return is_array($saved) ? array_merge($this->getDefaultSettings(), $saved) : $this->getDefaultSettings();
    }

    public function saveSettings(array $data): bool
    {
        $d = $this->getDefaultSettings();
        $c = [];
        $c['enabled']      = !empty($data['enabled']);
        $c['active_theme'] = in_array($data['active_theme'] ?? '', $this->getValidThemeIds(), true) ? $data['active_theme'] : $d['active_theme'];

        foreach (['tag_list', 'tag_single', 'tag_cloud'] as $k) {
            $c['scenes'][$k] = [
                'font_size'     => max(9, min(20, (int)($data['scenes'][$k]['font_size'] ?? $d['scenes'][$k]['font_size']))),
                'border_radius' => max(0, min(16, (int)($data['scenes'][$k]['border_radius'] ?? $d['scenes'][$k]['border_radius']))),
            ];
        }
        $c['colors'] = [
            'primary'   => $this->sanitizeColor($data['colors']['primary'] ?? '', $d['colors']['primary']),
            'secondary' => $this->sanitizeColor($data['colors']['secondary'] ?? '', $d['colors']['secondary']),
        ];
        $c['hash_style'] = in_array($data['hash_style'] ?? '', array_keys($this->getHashStyles()), true) ? $data['hash_style'] : $d['hash_style'];
        $c['hash_color'] = $this->sanitizeColor($data['hash_color'] ?? '', $d['hash_color']);

        Config::instance()->set('tag_style', $c);
        Config::instance()->save();
        delete_transient('xzd_tag_style_css');
        return true;
    }

    public function resetSettings(): array
    {
        Config::instance()->set('tag_style', $this->getDefaultSettings());
        Config::instance()->save();
        delete_transient('xzd_tag_style_css');
        return $this->getDefaultSettings();
    }

    public function getDefaultSettings(): array
    {
        return [
            'enabled'      => false,
            'active_theme' => 'outline',
            'scenes'       => [
                'tag_list'   => ['font_size' => 11, 'border_radius' => 3],
                'tag_single' => ['font_size' => 13, 'border_radius' => 6],
                'tag_cloud'  => ['font_size' => 12, 'border_radius' => 4],
            ],
            'colors'       => ['primary' => '#222222', 'secondary' => '#555555'],
            'hash_style'   => 'none',
            'hash_color'   => '#222222',
        ];
    }

    // ═══════════ 元数据 ═══════════

    public function getThemeMeta(): array
    {
        return [
            ['id' => 'outline',     'name' => '简约描边', 'desc' => '透明底+深色边框 · 悬停填色',  'colors' => 1],
            ['id' => 'soft-fill',   'name' => '柔和填充', 'desc' => '浅色背景+同系文字 · 悬停加深', 'colors' => 1],
            ['id' => 'gradient',    'name' => '渐变微光', 'desc' => '微渐变底+悬停发光阴影',       'colors' => 2],
            ['id' => 'bookmark',    'name' => '书签卡片', 'desc' => '白底+左侧色条+纸片投影',       'colors' => 1],
            ['id' => 'native',      'name' => '原生增强', 'desc' => '保留Zibll默认+悬停抬升阴影',   'colors' => 0],
        ];
    }

    public function getHashStyles(): array
    {
        return [
            'none' => '无',
            'dot'  => '彩点',
            'bar'  => '色条',
            'tag'  => '标签角',
        ];
    }

    // ═══════════ CSS 生成 ═══════════

    public function getCSS(): string
    {
        $cached = get_transient('xzd_tag_style_css');
        if ($cached !== false && is_string($cached)) return $cached;

        $s = $this->getSettings();
        if (empty($s['enabled'])) return '';

        $css = $this->generateCSS($s);
        if ($css) set_transient('xzd_tag_style_css', $css, DAY_IN_SECONDS);
        return $css;
    }

    public function previewCSS(array $params): string
    {
        return $this->generateCSS(array_merge($this->getDefaultSettings(), $params));
    }

    private function generateCSS(array $s): string
    {
        $c1 = esc_attr($s['colors']['primary']);
        $c2 = esc_attr($s['colors']['secondary']);
        $sc = $s['scenes'];
        $css = ":root{--xzd-tc:{$c1};--xzd-tc2:{$c2};}\n";

        // 场景字号/圆角
        $css .= ".xzd-tag-themed.xzd-tag-list{font-size:{$sc['tag_list']['font_size']}px;border-radius:{$sc['tag_list']['border_radius']}px;}\n";
        $css .= ".xzd-tag-themed.xzd-tag-single{font-size:{$sc['tag_single']['font_size']}px;border-radius:{$sc['tag_single']['border_radius']}px;}\n";
        $css .= ".xzd-tag-themed.xzd-tag-cloud{font-size:{$sc['tag_cloud']['font_size']}px !important;border-radius:{$sc['tag_cloud']['border_radius']}px;}\n";

        // 主题CSS
        switch ($s['active_theme']) {
            case 'outline':   $css .= $this->cssOutline($c1);   break;
            case 'soft-fill': $css .= $this->cssSoftFill($c1);  break;
            case 'gradient':  $css .= $this->cssGradient($c1, $c2); break;
            case 'bookmark':  $css .= $this->cssBookmark($c1);  break;
            case 'native':    $css .= $this->cssNative();        break;
        }

        // Hash CSS
        if ($s['hash_style'] !== 'none') {
            $css .= $this->cssHash($s['hash_style'], esc_attr($s['hash_color']));
        }

        return $css;
    }

    // ═══════════ 5套主题 ═══════════
    // ★ 核心设计：
    //   - 标签云(.xzd-tag-cloud)：继承Zibll随机颜色 --this-color，只改背景/边框样式
    //   - 文章标签(.xzd-tag-list/.xzd-tag-single)：无Zibll颜色类，使用 --xzd-tc
    //   - 使用 currentColor 让边框/阴影自动跟随文字颜色

    private function cssOutline(string $c1): string
    {
        // 透明底+边框继承文字色 → 悬停填色
        return "/* 简约描边 */
.xzd-tag-themed{font-weight:500;}
/* 文章标签：用配置颜色 */
.xzd-tag-themed.xzd-tag-list,.xzd-tag-themed.xzd-tag-single{background:transparent !important;color:{$c1} !important;border:1px solid {$c1} !important;}
.xzd-tag-themed.xzd-tag-list:hover,.xzd-tag-themed.xzd-tag-single:hover{color:#fff !important;background:{$c1} !important;}
/* 标签云：继承Zibll随机颜色，只设透明背景+实色边框 */
.xzd-tag-themed.xzd-tag-cloud{background:transparent !important;border:1px solid currentColor !important;}
.xzd-tag-themed.xzd-tag-cloud:hover{color:#fff !important;background:currentColor !important;}
/* 公共悬停 */
.xzd-tag-themed:hover{box-shadow:0 2px 8px rgba(0,0,0,.12);}\n";
    }

    private function cssSoftFill(string $c1): string
    {
        return "/* 柔和填充 */
.xzd-tag-themed{font-weight:500;}
/* 文章标签：用配置颜色 */
.xzd-tag-themed.xzd-tag-list,.xzd-tag-themed.xzd-tag-single{background:{$c1}15 !important;color:{$c1} !important;border:1px solid {$c1}30 !important;}
.xzd-tag-themed.xzd-tag-list:hover,.xzd-tag-themed.xzd-tag-single:hover{color:#fff !important;background:{$c1} !important;border-color:{$c1} !important;}
/* 标签云：保留Zibll底色+文字色，只改边框为同系 */
.xzd-tag-themed.xzd-tag-cloud{border:1px solid currentColor !important;border-color:color-mix(in srgb,currentColor 30%,transparent) !important;}
.xzd-tag-themed.xzd-tag-cloud:hover{color:#fff !important;background:currentColor !important;}
.xzd-tag-themed:hover{box-shadow:0 2px 8px rgba(0,0,0,.1);transform:translateY(-1px);}\n";
    }

    private function cssGradient(string $c1, string $c2): string
    {
        return "/* 渐变微光 */
.xzd-tag-themed{font-weight:500;}
/* 文章标签：用配置颜色组 */
.xzd-tag-themed.xzd-tag-list,.xzd-tag-themed.xzd-tag-single{background:linear-gradient(135deg,{$c1}10,{$c2}18) !important;color:{$c1} !important;border:1px solid {$c1}25 !important;}
.xzd-tag-themed.xzd-tag-list:hover,.xzd-tag-themed.xzd-tag-single:hover{background:linear-gradient(135deg,{$c1},{$c2}) !important;color:#fff !important;border-color:transparent !important;}
/* 标签云：保留Zibll随机色，渐变底替换为半透明 */
.xzd-tag-themed.xzd-tag-cloud{background:linear-gradient(135deg,color-mix(in srgb,currentColor 6%,transparent),color-mix(in srgb,currentColor 12%,transparent)) !important;border:1px solid color-mix(in srgb,currentColor 20%,transparent) !important;}
.xzd-tag-themed.xzd-tag-cloud:hover{color:#fff !important;background:linear-gradient(135deg,currentColor,color-mix(in srgb,currentColor 70%,#000)) !important;border-color:transparent !important;}
.xzd-tag-themed:hover{box-shadow:0 4px 14px rgba(0,0,0,.12);transform:translateY(-1px);}\n";
    }

    private function cssBookmark(string $c1): string
    {
        // 白底+左侧色条+纸片感
        return "/* 书签卡片 */
.xzd-tag-themed{font-weight:500;}
/* 文章标签：用配置颜色 */
.xzd-tag-themed.xzd-tag-list,.xzd-tag-themed.xzd-tag-single{background:#fff !important;color:#333 !important;border:1px solid #e5e7eb !important;border-left:3px solid {$c1} !important;box-shadow:0 1px 2px rgba(0,0,0,.04);}
.xzd-tag-themed.xzd-tag-list:hover,.xzd-tag-themed.xzd-tag-single:hover{color:{$c1} !important;border-color:{$c1}50 !important;border-left-color:{$c1} !important;}
/* 标签云：白底+保留随机色作为左边框色 */
.xzd-tag-themed.xzd-tag-cloud{background:#fff !important;border:1px solid #e5e7eb !important;border-left:3px solid currentColor !important;box-shadow:0 1px 2px rgba(0,0,0,.04);}
.xzd-tag-themed.xzd-tag-cloud:hover{border-color:color-mix(in srgb,currentColor 40%,#e5e7eb) !important;}
.xzd-tag-themed:hover{box-shadow:0 4px 12px rgba(0,0,0,.08);transform:translateY(-2px);}\n";
    }

    private function cssNative(): string
    {
        // 完全保留Zibll原生外观，仅加悬停微动效
        return "/* 原生增强 */
.xzd-tag-themed:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.12) !important;filter:brightness(1.05);}\n";
    }

    // ═══════════ Hash替换CSS ═══════════
    // ★ 使用 currentColor 让符号颜色自动跟随标签自身颜色（含Zibll随机色）

    private function cssHash(string $style, string $hc): string
    {
        $css = ".xzd-hash .xzd-hash-txt{display:none !important;}\n";

        switch ($style) {
            case 'dot':
                $css .= ".xzd-hash::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:currentColor;margin-right:5px;vertical-align:middle;flex-shrink:0;opacity:.85;}\n";
                break;
            case 'bar':
                $css .= ".xzd-hash{padding-left:10px !important;border-left:3px solid currentColor !important;}\n";
                break;
            case 'tag':
                $css .= ".xzd-hash{padding-right:16px !important;}\n";
                $css .= ".xzd-hash::after{content:'';position:absolute;right:0;top:0;width:0;height:0;border-style:solid;border-width:0 8px 8px 0;border-color:transparent currentColor transparent transparent;opacity:.85;}\n";
                break;
        }

        return $css;
    }

    // ═══════════ JS 注入 ═══════════

    public function injectJS(): void
    {
        $s = $this->getSettings();
        if (empty($s['enabled'])) return;
        ?>
        <script id="xzd-tag-js">
        (function(){
            if (window.__xzdTagInit) return;
            window.__xzdTagInit = true;
            var HASH = '<?php echo esc_js($s['hash_style']); ?>';

            function tagged(a) { return a.classList.contains('xzd-tag-themed'); }

            function scene(a) {
                var p = a.closest('.article-tags,.widget-tag-cloud,.widget_tag_cloud,.tagcloud,.item-tags');
                if (!p) return 'list';
                var c = p.className || '';
                if (/article-tags/.test(c)) return 'single';
                if (/widget-tag-cloud|widget_tag_cloud|tagcloud/.test(c)) return 'cloud';
                return 'list';
            }

            function hasTagURL(a) {
                return /\/tag\//.test(a.getAttribute('href') || '');
            }

            function process(a) {
                if (!hasTagURL(a) || tagged(a)) return;
                a.classList.add('xzd-tag-themed', 'xzd-tag-' + scene(a));
                if (HASH && HASH !== 'none') applyHash(a);
            }

            function applyHash(a) {
                if (a.classList.contains('xzd-hash')) return;
                var c = a.firstChild;
                while (c) {
                    if (c.nodeType === 3 && c.textContent.indexOf('# ') === 0) {
                        a.classList.add('xzd-hash');
                        var s = document.createElement('span');
                        s.className = 'xzd-hash-txt';
                        s.textContent = '# ';
                        c.textContent = c.textContent.slice(2);
                        a.insertBefore(s, c);
                        return;
                    }
                    c = c.nextSibling;
                }
            }

            function scan(root) {
                (root || document).querySelectorAll(
                    '.item-tags a[href*="/tag/"], .article-tags a[href*="/tag/"], .widget-tag-cloud a, .widget_tag_cloud a, .tagcloud a'
                ).forEach(process);
            }

            scan();
            if (window.MutationObserver) {
                new MutationObserver(function(ms) {
                    ms.forEach(function(m) {
                        m.addedNodes.forEach(function(n) {
                            if (n.nodeType === 1) { if (n.querySelectorAll) scan(n); }
                        });
                    });
                }).observe(document.body, { childList: true, subtree: true });
            }
        })();
        </script>
        <?php
    }

    public function injectCSS(): void
    {
        $css = $this->getCSS();
        if ($css) echo '<style id="xzd-tag-style">' . $css . '</style>';
    }

    // ═══════════ 辅助 ═══════════

    private function getValidThemeIds(): array
    {
        return array_map(fn($t) => $t['id'], $this->getThemeMeta());
    }

    private function sanitizeColor(string $color, string $default): string
    {
        $color = trim($color);
        if (empty($color)) return $default;
        if (preg_match('/^#[a-fA-F0-9]{3,8}$/', $color)) return $color;
        return $default;
    }
}
