"""LLM 없이 범용 경로(resolve → build_view → export) 검증.

(1) 샘플 ETF IR (자동매핑된 collection/fields)
(2) 임의 컴포넌트 구성(범용) — pie_chart, paragraph, bar_chart 등
두 케이스 모두 5종 export 가 동작하는지 확인한다.
"""
from __future__ import annotations

from pathlib import Path

from app.export.harness import SUPPORTED, export_report
from app.services.resolver import resolve
from app.services.view_model import build_view

FUND = "069500"


def db(table, columns, **kw):
    return {"type": "db", "datasetId": "kodex_etf_demo", "table": table, "columns": columns, **kw}


ETF_IR = {
    "schemaVersion": "1.0",
    "report": {
        "meta": {"title": "Kodex KODEX 200 ETF 이슈 리포트", "pageSize": "A4", "orientation": "portrait"},
        "background": {"id": "bg_000", "type": "background_image", "required": True, "layout": {"x": 0, "y": 0, "w": 12, "h": 50}},
        "grid": {"cols": 12, "rowUnit": 33, "gap": 8},
        "components": [
            {"id": "c1", "type": "metadata_text", "title": "발행 정보", "bbox": {"x": 0.1, "y": 0.1, "w": 0.3, "h": 0.06},
             "dataSpec": {"fields": [
                 {"key": "base_date", "label": "기준일", "role": "meta", "dataType": "date",
                  "binding": {"source": "column", "table": "etf_master", "column": "base_date"}},
                 {"key": "department", "label": "부서", "role": "meta", "dataType": "string",
                  "binding": {"source": "column", "table": "etf_master", "column": "department"}},
             ]}},
            {"id": "c2", "type": "line_chart", "title": "ETF 성과 추이", "bbox": {"x": 0.1, "y": 0.2, "w": 0.38, "h": 0.3},
             "dataSpec": {"collection": {
                 "enabled": True, "table": "etf_performance", "filterColumn": None, "filterValue": None,
                 "columns": [
                     {"label": "기간", "role": "x", "column": "period"},
                     {"label": "ETF", "role": "series", "column": "etf_return"},
                     {"label": "BM", "role": "series", "column": "benchmark_return"},
                 ], "orderBy": "period_order", "orderDir": "asc"}}},
            {"id": "c3", "type": "holdings_table", "title": "ETF Top 10 보유내역", "bbox": {"x": 0.5, "y": 0.2, "w": 0.4, "h": 0.3},
             "dataSpec": {"collection": {
                 "enabled": True, "table": "etf_holdings_top10", "filterColumn": None, "filterValue": None,
                 "columns": [
                     {"label": "No.", "role": "index", "column": None},
                     {"label": "종목명", "role": "name", "column": "holding_name"},
                     {"label": "보유비중(%)", "role": "value", "column": "weight"},
                 ], "orderBy": "weight", "orderDir": "desc", "limit": 10}}},
            {"id": "c4", "type": "bullet_list", "title": "ETF 리뷰", "bbox": {"x": 0.1, "y": 0.6, "w": 0.8, "h": 0.15},
             "dataSpec": {"fields": [
                 {"key": "performance_summary", "label": "성과 요약", "role": "narrative_input", "dataType": "text",
                  "binding": {"source": "column", "table": "etf_narrative_factors", "column": "performance_summary"}},
             ]}, "generatedBullets": ["최근 1개월 -4.89% 조정, 1년 19.69%로 양호.", "대형주 분산으로 손실 완화."]},
        ],
    },
}

GENERIC_IR = {
    "schemaVersion": "1.0",
    "report": {
        "meta": {"title": "임의 구성 보고서 (범용 테스트)", "pageSize": "A4", "orientation": "portrait"},
        "background": {"id": "bg_000", "type": "background_image", "required": True, "layout": {"x": 0, "y": 0, "w": 12, "h": 50}},
        "grid": {"cols": 12, "rowUnit": 33, "gap": 8},
        "components": [
            {"id": "g1", "type": "title", "title": "임의 구성 보고서",
             "dataSpec": {"fields": [{"key": "text", "label": "제목", "role": "title", "dataType": "string",
                                       "binding": {"source": "manual", "value": "임의 구성 보고서"}}]}},
            {"id": "g2", "type": "paragraph", "title": "개요",
             "dataSpec": {"fields": [{"key": "text", "label": "개요", "role": "scalar", "dataType": "text",
                                       "binding": {"source": "manual", "value": "이 페이지는 ETF 와 무관한 임의 컴포넌트 구성으로 범용 렌더를 검증한다."}}]}},
            {"id": "g3", "type": "pie_chart", "title": "구성 비중", "bbox": {"x": 0.1, "y": 0.3, "w": 0.4, "h": 0.3},
             "dataSpec": {"collection": {
                 "enabled": True, "table": "etf_holdings_top10", "filterColumn": None, "filterValue": None,
                 "columns": [
                     {"label": "항목", "role": "label", "column": "holding_name"},
                     {"label": "비중", "role": "value", "column": "weight"},
                 ], "orderBy": "weight", "orderDir": "desc", "limit": 5}}},
            {"id": "g4", "type": "table", "title": "임의 표", "bbox": {"x": 0.5, "y": 0.3, "w": 0.4, "h": 0.3},
             "dataSpec": {"collection": {
                 "enabled": True, "table": "etf_performance", "filterColumn": None, "filterValue": None,
                 "columns": [
                     {"label": "기간", "role": "name", "column": "period"},
                     {"label": "수익률", "role": "value", "column": "etf_return"},
                 ], "orderBy": "period_order", "orderDir": "asc"}}},
        ],
    },
}


def run_case(name: str, ir: dict) -> None:
    resolved = resolve({"schemaVersion": "1.0", "report": ir["report"]}, FUND)
    view = build_view(resolved)
    print(f"\n=== {name} ===")
    print("title:", view["title"], "| components:", len(view["components"]))
    for c in view["components"]:
        extra = ""
        if c.get("rows") is not None:
            extra = f" rows={len(c['rows'])} headers={c.get('headers')}"
        if c.get("series") is not None:
            extra = f" series={[s['name'] for s in c['series']]} cats={len(c.get('categories', []))}"
        if c.get("values") is not None:
            extra = f" pie values={len(c['values'])}"
        if c.get("bullets") is not None:
            extra = f" bullets={len(c['bullets'])}"
        print("  -", c["type"], "|", c.get("title", c.get("text", "")), extra)
    for fmt in SUPPORTED:
        try:
            r = export_report(fmt, view)
            print(f"  [OK] {fmt:5s} {r['size']} bytes")
        except Exception as e:  # noqa: BLE001
            print(f"  [FAIL] {fmt:5s} {e}")


def main():
    run_case("ETF 샘플", ETF_IR)
    run_case("임의 컴포넌트 구성", GENERIC_IR)


if __name__ == "__main__":
    main()
