"""Report generation for triangulation analyses.

Uses python-docx if available; otherwise produces a markdown report.
Imports are intentionally lazy so the CLI works without python-docx installed.
"""
from __future__ import annotations

from typing import Any


DISCLAIMER = (
    "본 도구는 연구 가설 생성·문헌 갭 분석 목적의 연구용·교육용 도구입니다. "
    "임상의사결정·환자 진료에 직접 사용해서는 안 되며, 모든 분석 결과는 추가 검증이 필요합니다."
)


def build_markdown_report(
    pair: tuple[str, str],
    pair_effects: list[dict[str, Any]],
    concordance: dict[str, Any],
    lawlor: dict[str, Any],
    biases: list[dict[str, Any]],
    designs: list[dict[str, Any]],
) -> str:
    drug_class, outcome = pair
    lines: list[str] = []
    lines.append(f"# Triangulation Report — {drug_class} × {outcome}")
    lines.append("")
    lines.append(f"> {DISCLAIMER}")
    lines.append("")
    lines.append("## 1. 5-design effect grid")
    lines.append("")
    lines.append("| design | drug | effect | 95% CI | n | f/u (y) | source |")
    lines.append("| --- | --- | ---: | --- | ---: | ---: | --- |")
    for r in pair_effects:
        ci = (
            f"{r.get('ci_low')}–{r.get('ci_high')}"
            if r.get("ci_low") is not None and r.get("ci_high") is not None
            else "NA"
        )
        lines.append(
            f"| {r.get('design','')} | {r.get('drug','')} | "
            f"{r.get('effect_estimate','')} | {ci} | "
            f"{r.get('sample_size') or 'NA'} | {r.get('follow_up_years') or 'NA'} | "
            f"{r.get('source_citation','')} |"
        )
    lines.append("")
    lines.append("## 2. Concordance metric")
    lines.append("")
    for k, v in concordance.items():
        lines.append(f"- {k}: {v}")
    lines.append("")
    lines.append("## 3. Lawlor 2016 5-criterion (each 0–2)")
    lines.append("")
    for c in lawlor["criteria"]:
        lines.append(f"- **{c['name']}**: {c['score']}/{c['max']} — {c['rationale']}")
    lines.append(
        f"- **total**: {lawlor['total']}/{lawlor['max']} "
        f"(normalized {lawlor['normalized']})"
    )
    lines.append("")
    lines.append("## 4. Discordance bias direction (ranked)")
    lines.append("")
    if not biases:
        lines.append("No discordance pattern triggered.")
    else:
        for b in biases:
            lines.append(
                f"- **{b['bias_type']}** (score {b['score']}): {b['rationale']}"
            )
            if b.get("definition"):
                lines.append(f"  - 정의: {b['definition']}")
    lines.append("")
    lines.append("## 5. Triangulation-targeted follow-up design cards")
    lines.append("")
    for i, c in enumerate(designs, 1):
        lines.append(f"### {i}. {c['name']} (match score {c['match_score']})")
        lines.append(f"- primary endpoint: {c['primary_endpoint']}")
        lines.append(f"- estimated n: {c['estimated_sample_size']}")
        lines.append(f"- follow-up: {c['follow_up_years']} years")
        lines.append(f"- addresses biases: {', '.join(c['addresses_biases'])}")
        lines.append(f"- key hypothesis: {c['key_hypothesis']}")
        lines.append(f"- rationale: {c['rationale']}")
        lines.append("")
    return "\n".join(lines)


def build_docx_report(
    pair: tuple[str, str],
    pair_effects: list[dict[str, Any]],
    concordance: dict[str, Any],
    lawlor: dict[str, Any],
    biases: list[dict[str, Any]],
    designs: list[dict[str, Any]],
    out_path: str,
) -> str:
    """Write a docx report. Requires python-docx; falls back to markdown.

    Returns the actual path written (may be .md if docx unavailable).
    """
    try:
        from docx import Document  # type: ignore
    except Exception:
        # Fallback: write a markdown file with the same stem
        md = build_markdown_report(pair, pair_effects, concordance, lawlor, biases, designs)
        if out_path.lower().endswith(".docx"):
            out_path = out_path[:-5] + ".md"
        with open(out_path, "w", encoding="utf-8") as f:
            f.write(md)
        return out_path

    drug_class, outcome = pair
    doc = Document()
    doc.add_heading(f"Triangulation Report — {drug_class} × {outcome}", level=1)
    p = doc.add_paragraph()
    p.add_run(DISCLAIMER).italic = True

    doc.add_heading("1. 5-design effect grid", level=2)
    table = doc.add_table(rows=1, cols=7)
    hdr = table.rows[0].cells
    for i, h in enumerate(["design", "drug", "effect", "95% CI", "n", "f/u (y)", "source"]):
        hdr[i].text = h
    for r in pair_effects:
        cells = table.add_row().cells
        cells[0].text = str(r.get("design", ""))
        cells[1].text = str(r.get("drug", ""))
        cells[2].text = str(r.get("effect_estimate", ""))
        cells[3].text = (
            f"{r.get('ci_low')}–{r.get('ci_high')}"
            if r.get("ci_low") is not None and r.get("ci_high") is not None
            else "NA"
        )
        cells[4].text = str(r.get("sample_size") or "NA")
        cells[5].text = str(r.get("follow_up_years") or "NA")
        cells[6].text = str(r.get("source_citation", ""))

    doc.add_heading("2. Concordance metric", level=2)
    for k, v in concordance.items():
        doc.add_paragraph(f"{k}: {v}", style="List Bullet")

    doc.add_heading("3. Lawlor 2016 5-criterion", level=2)
    for c in lawlor["criteria"]:
        doc.add_paragraph(
            f"{c['name']}: {c['score']}/{c['max']} — {c['rationale']}",
            style="List Bullet",
        )
    doc.add_paragraph(
        f"total: {lawlor['total']}/{lawlor['max']} (normalized {lawlor['normalized']})"
    )

    doc.add_heading("4. Discordance bias direction (ranked)", level=2)
    if not biases:
        doc.add_paragraph("No discordance pattern triggered.")
    else:
        for b in biases:
            doc.add_paragraph(
                f"{b['bias_type']} (score {b['score']}): {b['rationale']}",
                style="List Bullet",
            )

    doc.add_heading("5. Follow-up design cards", level=2)
    for i, c in enumerate(designs, 1):
        doc.add_heading(f"{i}. {c['name']} (match {c['match_score']})", level=3)
        doc.add_paragraph(f"primary endpoint: {c['primary_endpoint']}")
        doc.add_paragraph(f"estimated n: {c['estimated_sample_size']}")
        doc.add_paragraph(f"follow-up: {c['follow_up_years']} years")
        doc.add_paragraph(f"addresses biases: {', '.join(c['addresses_biases'])}")
        doc.add_paragraph(f"key hypothesis: {c['key_hypothesis']}")
        doc.add_paragraph(f"rationale: {c['rationale']}")

    doc.save(out_path)
    return out_path
