"""Export 하네스 — LLM HTML(정답 산출물)을 기준으로 모든 포맷을 통일 생성.

파이프라인:
  각 페이지 view + 원본 이미지 → LLM HTML 생성(레이아웃 재현) → 페이지 PNG 렌더
    - html : 페이지별 완성 HTML 합본
    - pdf  : 합본 HTML 을 Chromium 인쇄
    - pptx/docx/xlsx : 스킬 하네스가 (PNG 레퍼런스 + 구조화 데이터)로 빌더 코드 생성·실행
"""
from __future__ import annotations

import time
from pathlib import Path
from typing import Any

from app.config import settings
from app.export import skill_harness
from app.export.adapters import pdf_adapter
from app.services import render_llm

SUPPORTED = ["html", "pdf", "pptx", "docx", "xlsx"]
_EXT = {f: f for f in SUPPORTED}


def _result(fmt: str, filename: str, out_path: Path) -> dict[str, Any]:
    return {
        "format": fmt,
        "filename": filename,
        "path": str(out_path),
        "size": out_path.stat().st_size,
        "url": f"/api/download/{filename}",
    }


def _filename(title: str, ext: str) -> str:
    ts = int(time.time())
    raw = "".join(c for c in (title or "report") if c.isalnum() or c in " _-")[:40].strip()
    return f"{('_'.join(raw.split()) or 'report')}_{ts}.{ext}"


def _render_pages_llm(pages: list[dict[str, Any]]) -> tuple[list[str], list[dict[str, Any]]]:
    """각 페이지를 LLM HTML 로 생성. (페이지별 html 리스트, view 리스트) 반환."""
    htmls: list[str] = []
    views: list[dict[str, Any]] = []
    for p in pages:
        view = p.get("view") or p.get("viewModel") or {}
        ref = p.get("referenceImageDataUrl")
        bg = p.get("backgroundImageDataUrl")
        views.append(view)
        if not ref:
            raise ValueError("원본 이미지가 없어 레이아웃을 재현할 수 없습니다.")
        html, _ = render_llm.render_html_llm_from_dataurl(view, ref, bg)
        htmls.append(html)
    return htmls, views


def _combine_html(htmls: list[str]) -> str:
    """페이지별 완성 HTML 문서를 iframe srcdoc page-break 컨테이너로 합본."""
    body = "".join(
        f'<div class="pg"><iframe class="fr" srcdoc="{render_llm._attr(h)}"></iframe></div>'
        for h in htmls
    )
    style = (
        "<style>body{margin:0;background:#fff;}"
        ".pg{page-break-after:always;}.pg:last-child{page-break-after:auto;}"
        ".fr{width:210mm;height:297mm;border:0;display:block;}"
        "@media screen{body{background:#525659;}.pg{display:flex;justify-content:center;padding:16px 0;}"
        ".fr{box-shadow:0 2px 16px rgba(0,0,0,.3);background:#fff;}}</style>"
    )
    return f'<!doctype html><html lang="ko"><head><meta charset="utf-8">{style}</head><body>{body}</body></html>'


def export_pages(fmt: str, pages: list[dict[str, Any]]) -> dict[str, Any]:
    """멀티페이지 export. pages = [{view, referenceImageDataUrl, ...}, ...]. 한 파일로 합본."""
    fmt = (fmt or "").lower()
    if fmt not in SUPPORTED:
        raise ValueError(f"지원하지 않는 포맷: {fmt} (지원: {SUPPORTED})")
    if not pages:
        raise ValueError("페이지가 없습니다.")

    htmls, views = _render_pages_llm(pages)
    filename = _filename(views[0].get("title", "report"), _EXT[fmt])
    out_path = settings.output_path / filename

    if fmt == "html":
        out_path.write_text(_combine_html(htmls), encoding="utf-8")
    elif fmt == "pdf":
        pdf_adapter.export_html(_combine_html(htmls), out_path)
    else:
        # pptx/docx/xlsx: 첫 페이지 HTML 을 PNG 로 렌더해 레이아웃 레퍼런스로 사용
        ref_png = render_llm.render_page_png(htmls[0]) if htmls else None
        skill_harness.build(fmt, views, out_path, ref_png=ref_png)

    if not out_path.exists():
        raise RuntimeError(f"{fmt} 파일이 생성되지 않았습니다.")
    return _result(fmt, filename, out_path)


def export_report(
    fmt: str,
    vm: dict[str, Any],
    background_data_url: str | None = None,
    bg_opacity: float = 1.0,
    reference_image_data_url: str | None = None,
    background_image_data_url: str | None = None,
) -> dict[str, Any]:
    """단일 페이지 export — export_pages 로 위임."""
    page = {
        "view": vm,
        "referenceImageDataUrl": reference_image_data_url or background_data_url,
        "backgroundImageDataUrl": background_image_data_url,
    }
    return export_pages(fmt, [page])
