using System.IO;
using System.Text;
using System.Text.Json;

namespace AxCopilot.Services.Agent;

public partial class DocumentPlannerTool
{
    // ─── 파일 생성: HTML / DOCX / Markdown ──────────────────────────────────

    private static void GenerateHtml(string path, string title, string docType, List<SectionPlan> sections)
    {
        var css = TemplateService.GetCss("professional");
        var sb = new StringBuilder();

        sb.AppendLine("<!DOCTYPE html>");
        sb.AppendLine("<html lang=\"ko\">");
        sb.AppendLine("<head>");
        sb.AppendLine("<meta charset=\"utf-8\">");
        sb.AppendLine($"<title>{Escape(title)}</title>");
        sb.AppendLine("<style>");
        sb.AppendLine(css);
        sb.AppendLine(@"
.doc { max-width: 900px; margin: 0 auto; padding: 40px 30px 60px; }
.doc h1 { font-size: 28px; margin-bottom: 8px; border-bottom: 3px solid var(--accent, #4B5EFC); padding-bottom: 10px; }
.doc h2 { font-size: 22px; margin-top: 36px; margin-bottom: 12px; border-bottom: 2px solid var(--accent, #4B5EFC); padding-bottom: 6px; }
.doc .meta { color: #888; font-size: 13px; margin-bottom: 24px; }
.doc .section { line-height: 1.8; margin-bottom: 20px; }
.doc .toc { background: #f8f9fa; border-radius: 12px; padding: 20px 28px; margin: 24px 0 32px; }
.doc .toc h3 { margin-top: 0; }
.doc .toc a { color: inherit; text-decoration: none; }
.doc .toc a:hover { text-decoration: underline; }
.doc .toc ul { list-style: none; padding-left: 0; }
.doc .toc li { padding: 4px 0; }
.doc .key-point { background: #f0f4ff; border-left: 4px solid var(--accent, #4B5EFC); padding: 12px 16px; margin: 12px 0; border-radius: 0 8px 8px 0; }
@media print { .doc h2 { page-break-before: auto; } }
");
        sb.AppendLine("</style>");
        sb.AppendLine("</head>");
        sb.AppendLine("<body>");
        sb.AppendLine("<div class=\"doc\">");
        sb.AppendLine($"<h1>{Escape(title)}</h1>");
        sb.AppendLine($"<div class=\"meta\">문서 유형: {Escape(GetDocTypeLabel(docType))} | 작성일: {DateTime.Now:yyyy-MM-dd} | 섹션: {sections.Count}개</div>");

        // 목차
        if (sections.Count > 1)
        {
            sb.AppendLine("<div class=\"toc\">");
            sb.AppendLine("<h3>📋 목차</h3>");
            sb.AppendLine("<ul>");
            for (int i = 0; i < sections.Count; i++)
                sb.AppendLine($"<li><a href=\"#sec-{i + 1}\">{Escape(sections[i].Heading)}</a></li>");
            sb.AppendLine("</ul>");
            sb.AppendLine("</div>");
        }

        // 섹션 본문
        for (int i = 0; i < sections.Count; i++)
        {
            var sec = sections[i];
            sb.AppendLine($"<h2 id=\"sec-{i + 1}\">{Escape(sec.Heading)}</h2>");
            sb.AppendLine("<div class=\"section\">");
            foreach (var kp in sec.KeyPoints)
            {
                sb.AppendLine($"<div class=\"key-point\">");
                sb.AppendLine($"<strong>▸ {Escape(kp)}</strong>");
                sb.AppendLine($"<p>{Escape(kp)}에 대한 상세 내용을 여기에 작성합니다. (목표: 약 {sec.TargetWords / Math.Max(1, sec.KeyPoints.Count)}단어)</p>");
                sb.AppendLine("</div>");
            }
            sb.AppendLine("</div>");
        }

        sb.AppendLine("</div>");
        sb.AppendLine("</body>");
        sb.AppendLine("</html>");

        File.WriteAllText(path, sb.ToString(), Encoding.UTF8);
    }

    // ─── DOCX 생성 ──────────────────────────────────────────────────────────

    private static void GenerateDocx(string path, string title, List<SectionPlan> sections)
    {
        using var doc = DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Create(
            path, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);

        var mainPart = doc.AddMainDocumentPart();
        mainPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
        var body = mainPart.Document.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Body());

        // 제목
        AddDocxParagraph(body, title, bold: true, fontSize: "48");
        AddDocxParagraph(body, $"작성일: {DateTime.Now:yyyy-MM-dd}", fontSize: "20", color: "888888");
        AddDocxParagraph(body, ""); // 빈 줄

        foreach (var sec in sections)
        {
            AddDocxParagraph(body, sec.Heading, bold: true, fontSize: "32", color: "2B579A");
            foreach (var kp in sec.KeyPoints)
            {
                AddDocxParagraph(body, $"▸ {kp}", bold: true, fontSize: "22");
                AddDocxParagraph(body, $"{kp}에 대한 상세 내용을 여기에 작성합니다.");
            }
            AddDocxParagraph(body, ""); // 섹션 간 빈 줄
        }
    }

    private static void AddDocxParagraph(DocumentFormat.OpenXml.Wordprocessing.Body body,
        string text, bool bold = false, string fontSize = "22", string? color = null)
    {
        var para = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
        var run = new DocumentFormat.OpenXml.Wordprocessing.Run();
        var props = new DocumentFormat.OpenXml.Wordprocessing.RunProperties
        {
            FontSize = new DocumentFormat.OpenXml.Wordprocessing.FontSize { Val = fontSize }
        };
        if (bold) props.Bold = new DocumentFormat.OpenXml.Wordprocessing.Bold();
        if (color != null) props.Color = new DocumentFormat.OpenXml.Wordprocessing.Color { Val = color };
        run.AppendChild(props);
        run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text(text)
        {
            Space = DocumentFormat.OpenXml.SpaceProcessingModeValues.Preserve
        });
        para.AppendChild(run);
        body.AppendChild(para);
    }

    // ─── Markdown 생성 ──────────────────────────────────────────────────────

    private static void GenerateMarkdown(string path, string title, List<SectionPlan> sections)
    {
        var sb = new StringBuilder();
        sb.AppendLine($"# {title}");
        sb.AppendLine();
        sb.AppendLine($"*작성일: {DateTime.Now:yyyy-MM-dd}*");
        sb.AppendLine();

        // 목차
        if (sections.Count > 1)
        {
            sb.AppendLine("## 목차");
            sb.AppendLine();
            foreach (var sec in sections)
                sb.AppendLine($"- [{sec.Heading}](#{sec.Heading.Replace(" ", "-").ToLowerInvariant()})");
            sb.AppendLine();
            sb.AppendLine("---");
            sb.AppendLine();
        }

        foreach (var sec in sections)
        {
            sb.AppendLine($"## {sec.Heading}");
            sb.AppendLine();
            foreach (var kp in sec.KeyPoints)
            {
                sb.AppendLine($"### ▸ {kp}");
                sb.AppendLine();
                sb.AppendLine($"{kp}에 대한 상세 내용을 여기에 작성합니다.");
                sb.AppendLine();
            }
        }

        File.WriteAllText(path, sb.ToString(), Encoding.UTF8);
    }

    // ─── 헬퍼 ────────────────────────────────────────────────────────────────

    private static List<SectionPlan> BuildSections(string docType, int pages, string hint, string refSummary)
    {
        if (!string.IsNullOrWhiteSpace(hint))
        {
            var hintSections = hint.Split(new[] { ',', '/', '→', '\n' }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
            var result = new List<SectionPlan>();
            for (int i = 0; i < hintSections.Length; i++)
            {
                result.Add(new SectionPlan
                {
                    Id = $"sec-{i + 1}",
                    Heading = $"{i + 1}. {hintSections[i].TrimStart("0123456789. ".ToCharArray())}",
                    Level = 1,
                    KeyPoints = [$"{hintSections[i]} 관련 핵심 내용을 상세히 작성"],
                });
            }
            return result;
        }

        return docType switch
        {
            "proposal" => new List<SectionPlan>
            {
                new() { Id = "sec-1", Heading = "1. 개요", Level = 1, KeyPoints = ["배경", "목적", "범위"] },
                new() { Id = "sec-2", Heading = "2. 현황 분석", Level = 1, KeyPoints = ["현재 상황", "문제점 식별"] },
                new() { Id = "sec-3", Heading = "3. 제안 내용", Level = 1, KeyPoints = ["핵심 제안", "기대 효과", "실행 방안"] },
                new() { Id = "sec-4", Heading = "4. 추진 일정", Level = 1, KeyPoints = ["단계별 일정", "마일스톤"] },
                new() { Id = "sec-5", Heading = "5. 소요 자원", Level = 1, KeyPoints = ["인력", "예산", "장비"] },
                new() { Id = "sec-6", Heading = "6. 기대 효과 및 결론", Level = 1, KeyPoints = ["정량적 효과", "정성적 효과", "결론"] },
            },
            "analysis" => new List<SectionPlan>
            {
                new() { Id = "sec-1", Heading = "1. 분석 개요", Level = 1, KeyPoints = ["분석 목적", "분석 범위", "방법론"] },
                new() { Id = "sec-2", Heading = "2. 데이터 현황", Level = 1, KeyPoints = ["데이터 출처", "기본 통계", "데이터 품질"] },
                new() { Id = "sec-3", Heading = "3. 정량 분석", Level = 1, KeyPoints = ["수치 분석", "추세", "비교"] },
                new() { Id = "sec-4", Heading = "4. 정성 분석", Level = 1, KeyPoints = ["패턴", "인사이트", "이상치"] },
                new() { Id = "sec-5", Heading = "5. 종합 해석", Level = 1, KeyPoints = ["핵심 발견", "시사점"] },
                new() { Id = "sec-6", Heading = "6. 결론 및 권장사항", Level = 1, KeyPoints = ["결론", "조치 방안", "추가 분석 필요 항목"] },
            },
            "manual" or "guide" => new List<SectionPlan>
            {
                new() { Id = "sec-1", Heading = "1. 소개", Level = 1, KeyPoints = ["목적", "대상 독자", "사전 요구사항"] },
                new() { Id = "sec-2", Heading = "2. 시작하기", Level = 1, KeyPoints = ["설치", "초기 설정", "기본 사용법"] },
                new() { Id = "sec-3", Heading = "3. 주요 기능", Level = 1, KeyPoints = ["기능별 상세 설명", "사용 예시"] },
                new() { Id = "sec-4", Heading = "4. 고급 기능", Level = 1, KeyPoints = ["고급 설정", "커스터마이징", "자동화"] },
                new() { Id = "sec-5", Heading = "5. 문제 해결", Level = 1, KeyPoints = ["자주 묻는 질문", "에러 대응", "지원 정보"] },
            },
            "minutes" => new List<SectionPlan>
            {
                new() { Id = "sec-1", Heading = "1. 회의 정보", Level = 1, KeyPoints = ["일시", "참석자", "장소"] },
                new() { Id = "sec-2", Heading = "2. 안건 및 논의", Level = 1, KeyPoints = ["안건별 논의 내용", "주요 의견"] },
                new() { Id = "sec-3", Heading = "3. 결정 사항", Level = 1, KeyPoints = ["합의 내용", "변경 사항"] },
                new() { Id = "sec-4", Heading = "4. 액션 아이템", Level = 1, KeyPoints = ["담당자", "기한", "세부 내용"] },
                new() { Id = "sec-5", Heading = "5. 다음 회의", Level = 1, KeyPoints = ["예정일", "주요 안건"] },
            },
            _ => new List<SectionPlan>
            {
                new() { Id = "sec-1", Heading = "1. 개요", Level = 1, KeyPoints = ["배경", "목적", "범위"] },
                new() { Id = "sec-2", Heading = "2. 현황", Level = 1, KeyPoints = ["현재 상태", "주요 지표"] },
                new() { Id = "sec-3", Heading = "3. 분석", Level = 1, KeyPoints = ["데이터 분석", "비교", "추세"] },
                new() { Id = "sec-4", Heading = "4. 주요 발견", Level = 1, KeyPoints = ["핵심 인사이트", "문제점", "기회"] },
                new() { Id = "sec-5", Heading = "5. 제안", Level = 1, KeyPoints = ["개선 방안", "실행 계획"] },
                new() { Id = "sec-6", Heading = "6. 결론", Level = 1, KeyPoints = ["요약", "기대 효과", "향후 과제"] },
            },
        };
    }

    private static void DistributeWordCount(List<SectionPlan> sections, int totalWords)
    {
        if (sections.Count == 0) return;
        var weights = new double[sections.Count];
        for (int i = 0; i < sections.Count; i++)
            weights[i] = (i == 0 || i == sections.Count - 1) ? 0.7 : 1.2;

        var totalWeight = weights.Sum();
        for (int i = 0; i < sections.Count; i++)
            sections[i].TargetWords = Math.Max(100, (int)(totalWords * weights[i] / totalWeight));
    }

    private static string SanitizeFileName(string name)
    {
        var safe = name.Length > 60 ? name[..60] : name;
        foreach (var c in Path.GetInvalidFileNameChars())
            safe = safe.Replace(c, '_');
        return safe.Trim().TrimEnd('.');
    }

    private static string GetDocTypeLabel(string docType) => docType switch
    {
        "proposal" => "제안서",
        "analysis" => "분석 보고서",
        "manual" or "guide" => "매뉴얼/가이드",
        "minutes" => "회의록",
        "presentation" => "프레젠테이션",
        _ => "보고서",
    };

    private static string Escape(string text)
        => text.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");

    private static readonly JsonSerializerOptions _jsonOptions = new()
    {
        WriteIndented = true,
        Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    };

    private class SectionPlan
    {
        public string Id { get; set; } = "";
        public string Heading { get; set; } = "";
        public int Level { get; set; } = 1;
        public int TargetWords { get; set; } = 300;
        public List<string> KeyPoints { get; set; } = new();
    }
}
