using Markdig;

namespace AxCopilot.Services.Agent;

/// <summary>
/// 문서 디자인 템플릿 서비스.
/// 테마 무드(현대적, 전문가, 창의적 등)에 따라 CSS 스타일을 제공합니다.
/// HtmlSkill, DocxSkill 등에서 호출하여 문서 생성 시 적용합니다.
/// </summary>
public static partial class TemplateService
{
    /// <summary>사용 가능한 테마 무드 목록.</summary>
    public static readonly TemplateMood[] AvailableMoods =
    [
        new("modern",       "현대적",        "🔷", "깔끔한 라인, 넓은 여백, 미니멀한 색상 — 테크 기업 스타일"),
        new("professional", "전문가",        "📊", "신뢰감 있는 네이비 톤, 데이터 중심 레이아웃 — 비즈니스 보고서"),
        new("creative",     "아이디어",      "🎨", "생동감 있는 그라데이션, 카드 레이아웃 — 브레인스토밍·기획서"),
        new("minimal",      "미니멀",        "◻️", "극도로 절제된 흑백, 타이포그래피 중심 — 학술·논문 스타일"),
        new("elegant",      "우아한",        "✨", "세리프 서체, 골드 포인트, 격식 있는 레이아웃 — 공식 문서"),
        new("dark",         "다크 모드",     "🌙", "어두운 배경, 고대비 텍스트 — 개발자·야간 리딩"),
        new("colorful",     "컬러풀",        "🌈", "밝고 활기찬 멀티 컬러, 둥근 모서리 — 프레젠테이션·요약"),
        new("corporate",    "기업 공식",     "🏢", "보수적인 레이아웃, 로고 영역, 페이지 번호 — 사내 공식 보고서"),
        new("magazine",     "매거진",        "📰", "멀티 컬럼, 큰 히어로 헤더, 인용 강조 — 뉴스레터·매거진"),
        new("dashboard",    "대시보드",      "📈", "KPI 카드, 차트 영역, 그리드 레이아웃 — 데이터 대시보드"),
    ];

    // ── 커스텀 무드 저장소 ──
    private static readonly Dictionary<string, Models.CustomMoodEntry> _customMoods = new(StringComparer.OrdinalIgnoreCase);

    /// <summary>커스텀 무드를 로드합니다 (앱 시작 시 SettingsService에서 호출).</summary>
    public static void LoadCustomMoods(IEnumerable<Models.CustomMoodEntry> entries)
    {
        _customMoods.Clear();
        foreach (var e in entries)
            if (!string.IsNullOrWhiteSpace(e.Key))
                _customMoods[e.Key] = e;
    }

    /// <summary>내장 + 커스텀 무드를 합친 전체 목록.</summary>
    public static IReadOnlyList<TemplateMood> AllMoods
    {
        get
        {
            var list = new List<TemplateMood>(AvailableMoods);
            foreach (var cm in _customMoods.Values)
                list.Add(new TemplateMood(cm.Key, cm.Label, cm.Icon, cm.Description));
            return list;
        }
    }

    /// <summary>무드 키로 CSS 스타일을 반환합니다. 없으면 modern 기본값. 공통 CSS가 자동 첨부됩니다.</summary>
    public static string GetCss(string moodKey)
    {
        // 커스텀 무드 우선 확인
        if (_customMoods.TryGetValue(moodKey, out var custom))
            return custom.Css + "\n" + CssShared;

        var moodCss = moodKey switch
        {
            "modern"       => CssModern,
            "professional" => CssProfessional,
            "creative"     => CssCreative,
            "minimal"      => CssMinimal,
            "elegant"      => CssElegant,
            "dark"         => CssDark,
            "colorful"     => CssColorful,
            "corporate"    => CssCorporate,
            "magazine"     => CssMagazine,
            "dashboard"    => CssDashboard,
            _              => CssModern,
        };
        return moodCss + "\n" + CssShared;
    }

    /// <summary>무드 키로 TemplateMood를 반환합니다.</summary>
    public static TemplateMood? GetMood(string key)
    {
        var builtin = Array.Find(AvailableMoods, m => m.Key == key);
        if (builtin != null) return builtin;
        return _customMoods.TryGetValue(key, out var cm)
            ? new TemplateMood(cm.Key, cm.Label, cm.Icon, cm.Description)
            : null;
    }

    /// <summary>LLM 시스템 프롬프트에 삽입할 무드 목록 설명.</summary>
    public static string GetMoodListForPrompt()
    {
        var sb = new System.Text.StringBuilder();
        sb.AppendLine("Available document design moods (pass as 'mood' parameter to html_create):");
        foreach (var m in AllMoods)
            sb.AppendLine($"  - \"{m.Key}\": {m.Label} — {m.Description}");
        return sb.ToString();
    }

    /// <summary>Markdown 텍스트를 무드 CSS가 적용된 HTML 문서로 변환합니다.</summary>
    public static string RenderMarkdownToHtml(string markdown, string moodKey = "modern")
    {
        var pipeline = new MarkdownPipelineBuilder()
            .UseAdvancedExtensions()
            .Build();
        var bodyHtml = Markdown.ToHtml(markdown, pipeline);
        var css = GetCss(moodKey);
        return $"""
            <!DOCTYPE html>
            <html lang="ko">
            <head>
            <meta charset="UTF-8"/>
            <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
            <style>{css}</style>
            </head>
            <body>
            <div class="container">
            {bodyHtml}
            </div>
            </body>
            </html>
            """;
    }

    /// <summary>
    /// HTML 본문에서 워크스페이스 하위 파일/폴더 경로를 파란색으로 강조합니다.
    /// 코드 블록(&lt;code&gt;, &lt;pre&gt;) 내부의 경로 텍스트를 감지하여 파란색 스타일을 적용합니다.
    /// </summary>
    public static string HighlightFilePaths(string html, string? workFolder)
    {
        if (string.IsNullOrEmpty(workFolder) || string.IsNullOrEmpty(html))
            return html;

        // <code> 태그 내부의 텍스트 중 파일/폴더 경로 패턴을 감지하여 파란색으로 감싸기
        // 패턴: 슬래시/백슬래시를 포함한 경로 또는 확장자가 있는 파일명
        var pathPattern = new System.Text.RegularExpressions.Regex(
            @"(?<![""'=/>])(\b[A-Za-z]:\\[^\s<>""]+|" +           // 절대 경로: C:\folder\file.ext
            @"\.{0,2}/[^\s<>""]+(?:\.[a-zA-Z]{1,10})?|" +         // 상대 경로: ./src/file.cs, ../util.py
            @"\b[\w\-]+(?:/[\w\-\.]+)+(?:\.[a-zA-Z]{1,10})?|" +   // 폴더/파일: src/utils/helper.cs
            @"\b[\w\-]+\.(?:cs|py|js|ts|tsx|jsx|json|xml|html|htm|css|md|txt|yml|yaml|toml|sh|bat|ps1|csproj|sln|docx|xlsx|pptx|pdf|csv)\b)", // 파일명.확장자
            System.Text.RegularExpressions.RegexOptions.Compiled);

        // <pre> 및 <code> 블록 외부의 텍스트에서만 치환
        // 간단 접근: 모든 텍스트 노드에서 경로를 감지
        return pathPattern.Replace(html, match =>
        {
            var path = match.Value;
            // 이미 HTML 태그 내부이거나 href/src 속성값이면 건너뛰기
            var prefix = html[..match.Index];
            if (prefix.Length > 0)
            {
                var lastLt = prefix.LastIndexOf('<');
                var lastGt = prefix.LastIndexOf('>');
                if (lastLt > lastGt) return path; // 태그 속성 내부
            }
            return $"<span style=\"color:#3B82F6;font-weight:500;\">{path}</span>";
        });
    }

    /// <summary>무드의 주요 색상을 반환합니다 (갤러리 미리보기용).</summary>
    public static MoodColors GetMoodColors(string moodKey)
    {
        return moodKey switch
        {
            "modern"       => new("#f5f5f7", "#ffffff", "#1d1d1f", "#6e6e73", "#0066cc", "#e5e5e7"),
            "professional" => new("#f0f2f5", "#ffffff", "#1a365d", "#4a5568", "#2c5282", "#e2e8f0"),
            "creative"     => new("#faf5ff", "#ffffff", "#2d3748", "#718096", "#7c3aed", "#e9d5ff"),
            "minimal"      => new("#fafafa", "#ffffff", "#111111", "#555555", "#333333", "#e0e0e0"),
            "elegant"      => new("#fefdf8", "#fffef9", "#2c1810", "#6b5c4f", "#b8860b", "#e8e0d4"),
            "dark"         => new("#0d1117", "#161b22", "#e6edf3", "#8b949e", "#58a6ff", "#30363d"),
            "colorful"     => new("#f0f9ff", "#ffffff", "#1e293b", "#64748b", "#3b82f6", "#e0f2fe"),
            "corporate"    => new("#f3f4f6", "#ffffff", "#1f2937", "#6b7280", "#1e40af", "#e5e7eb"),
            "magazine"     => new("#f9fafb", "#ffffff", "#111827", "#6b7280", "#dc2626", "#f3f4f6"),
            "dashboard"    => new("#0f172a", "#1e293b", "#f1f5f9", "#94a3b8", "#3b82f6", "#334155"),
            _              => new("#f5f5f7", "#ffffff", "#1d1d1f", "#6e6e73", "#0066cc", "#e5e5e7"),
        };
    }

    /// <summary>무드 갤러리용 색상 정보.</summary>
    public record MoodColors(string Background, string CardBg, string PrimaryText, string SecondaryText, string Accent, string Border);
}

/// <summary>테마 무드 정의.</summary>
public record TemplateMood(string Key, string Label, string Icon, string Description);
