"""Report export — Markdown always, .docx if python-docx available."""
from __future__ import annotations

import json
from typing import Dict, List, Optional

from . import DISCLAIMER
from .bias import diagnose_discordance, BIAS_TAXONOMY
from .designs import proposed_designs
from .grid import build_grid, grid_as_table
from .lawlor import score_pair, korean_ancestry_layer_score
from .mediation import masld_mediated_fraction
from .mvmr import mvmr_decompose
from .ontology import filter_effects


def build_full_report(effects: List[Dict[str, object]]) -> Dict[str, object]:
    grid = build_grid(effects)
    discordant = [g for g in grid if g["concordance"]["label"] == "DISCORDANT"]
    high = [g for g in grid if g["concordance"]["label"] == "HIGH_CONCORDANCE"]

    pair_details = []
    for g in grid[:10]:
        s, o = g["stage"], g["outcome"]
        pair_details.append({
            "stage": s,
            "outcome": o,
            "concordance": g["concordance"],
            "lawlor": score_pair(g["designs"]),
            "mvmr": mvmr_decompose(effects, s, o),
            "mediation": masld_mediated_fraction(effects, s, o),
            "bias": diagnose_discordance(effects, s, o),
        })

    return {
        "disclaimer": DISCLAIMER,
        "n_pairs": len(grid),
        "n_discordant": len(discordant),
        "n_high_concordance": len(high),
        "grid_summary": [
            {"stage": g["stage"], "outcome": g["outcome"],
             "label": g["concordance"]["label"], "score": g["concordance"]["score"],
             "n_designs": g["concordance"]["n_designs"]}
            for g in grid
        ],
        "korean_layer": korean_ancestry_layer_score(effects),
        "pair_details_top10": pair_details,
        "designs_universal": proposed_designs()["cards"],
        "bias_taxonomy": BIAS_TAXONOMY,
    }


def report_to_markdown(report: Dict[str, object]) -> str:
    L: List[str] = []
    L.append("# MASLDTriangulate-Kor 리포트")
    L.append("")
    L.append("> " + report["disclaimer"])
    L.append("")
    L.append(f"- 분석 pair 수: **{report['n_pairs']}**")
    L.append(f"- HIGH concordance: **{report['n_high_concordance']}** / DISCORDANT: **{report['n_discordant']}**")
    kl = report["korean_layer"]
    L.append(f"- Korean ancestry external validity: **{kl['external_validity_for_korean']}** "
             f"(rows={kl['n_korean_rows']}, designs={kl['korean_designs_covered']})")
    L.append("")
    L.append("## 5-design grid 요약")
    L.append("")
    L.append("| stage | outcome | label | score | n_designs |")
    L.append("|---|---|---|---|---|")
    for g in report["grid_summary"]:
        L.append(f"| {g['stage']} | {g['outcome']} | {g['label']} | "
                 f"{g['score']} | {g['n_designs']} |")
    L.append("")
    L.append("## Top 10 pair detail")
    for pd in report["pair_details_top10"]:
        L.append("")
        L.append(f"### {pd['stage']} × {pd['outcome']}  [{pd['concordance']['label']}]")
        L.append(f"- Lawlor total: {pd['lawlor']['total']}/5  (criteria: {pd['lawlor']['criteria']})")
        mv = pd["mvmr"]
        if mv.get("available"):
            L.append(f"- MVMR liver-specific effect: {mv.get('liver_specific_effect')} | "
                     f"metabolic confounder: {mv.get('metabolic_confounder_effect')}")
            L.append(f"- MVMR interpretation: {mv.get('interpretation')}")
        med = pd["mediation"]
        if med.get("mediation_available"):
            L.append(f"- Mediation: MASLD {med['frac_masld_mediated']} / "
                     f"metabolic {med['frac_metabolic_mediated']} / "
                     f"residual {med['residual_effect_unmeasured']}")
            L.append(f"- 해석: {med.get('interpretation')}")
        bf = pd["bias"]
        if bf["flags"]:
            L.append(f"- Bias flags ({bf['n_flags']}):")
            for f in bf["flags"]:
                L.append(f"  - **{f['code']}** — {f['trigger']}")
    L.append("")
    L.append("## 8 triangulation-targeted 후속 design")
    for c in report["designs_universal"]:
        L.append(f"- **{c['type']}** ({c['tier']})  — {c['rationale']}")
    L.append("")
    L.append("## Bias taxonomy")
    for b in report["bias_taxonomy"]:
        L.append(f"- **{b['code']}** ({b['name']}) — {b['description']}")
    return "\n".join(L)


def report_to_json(report: Dict[str, object]) -> str:
    return json.dumps(report, ensure_ascii=False, indent=2, default=str)


def save_docx(report: Dict[str, object], path: str) -> Dict[str, object]:
    """Save .docx if python-docx available, else fall back to .md."""
    try:
        from docx import Document  # type: ignore
    except Exception as e:
        md = report_to_markdown(report)
        mdpath = path.replace(".docx", ".md")
        with open(mdpath, "w", encoding="utf-8") as f:
            f.write(md)
        return {"format": "markdown_fallback", "path": mdpath, "reason": str(e)}

    doc = Document()
    doc.add_heading("MASLDTriangulate-Kor 리포트", level=0)
    p = doc.add_paragraph()
    p.add_run(report["disclaimer"]).italic = True
    doc.add_heading("요약", level=1)
    doc.add_paragraph(
        f"분석 pair: {report['n_pairs']} / HIGH {report['n_high_concordance']} / "
        f"DISCORDANT {report['n_discordant']}"
    )

    doc.add_heading("5-design grid 요약", level=1)
    table = doc.add_table(rows=1, cols=5)
    hdr = table.rows[0].cells
    for i, h in enumerate(["stage", "outcome", "label", "score", "n_designs"]):
        hdr[i].text = h
    for g in report["grid_summary"]:
        row = table.add_row().cells
        row[0].text = str(g["stage"])
        row[1].text = str(g["outcome"])
        row[2].text = str(g["label"])
        row[3].text = str(g["score"])
        row[4].text = str(g["n_designs"])

    doc.add_heading("Top pair 상세", level=1)
    for pd in report["pair_details_top10"]:
        doc.add_heading(f"{pd['stage']} × {pd['outcome']}", level=2)
        doc.add_paragraph(f"Concordance: {pd['concordance']['label']} "
                          f"(score {pd['concordance']['score']})")
        doc.add_paragraph(f"Lawlor 5-criterion: {pd['lawlor']['total']}/5")
        mv = pd["mvmr"]
        if mv.get("available"):
            doc.add_paragraph(
                f"MVMR liver-specific: {mv.get('liver_specific_effect')} / "
                f"metabolic: {mv.get('metabolic_confounder_effect')}"
            )

    doc.add_heading("8 triangulation-targeted design", level=1)
    for c in report["designs_universal"]:
        doc.add_paragraph(f"{c['type']} — {c['rationale']}", style="List Bullet")

    doc.save(path)
    return {"format": "docx", "path": path}
