"""
Render the PRISMA 2020 flow diagram for the umbrella review as a publication-quality PNG.

Style: journal-friendly (sans-serif, muted accent, white background).
Output:  prisma_flow.png  (300 dpi, ~6 inches wide)

Usage:
    python prisma_flow.py
"""
from __future__ import annotations
from pathlib import Path

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch

OUT_PNG = Path(__file__).resolve().parent / "prisma_flow.png"

# Muted palette
COL_BOX = "#FFFFFF"
COL_BOX_EXC = "#FBEAEA"   # accent for exclusion boxes
COL_BORDER = "#222222"
COL_TEXT = "#222222"
COL_HEADER = "#444444"


def add_box(ax, x, y, w, h, text, fillcolor=COL_BOX, fontsize=8.5, weight="normal"):
    box = FancyBboxPatch(
        (x, y), w, h,
        boxstyle="round,pad=0.02,rounding_size=0.04",
        linewidth=0.9, edgecolor=COL_BORDER, facecolor=fillcolor,
    )
    ax.add_patch(box)
    ax.text(x + w / 2, y + h / 2, text,
            ha="center", va="center", fontsize=fontsize,
            color=COL_TEXT, weight=weight, family="DejaVu Sans")


def add_header(ax, x, y, text):
    ax.text(x, y, text, ha="left", va="center",
            fontsize=10, weight="bold", color=COL_HEADER, family="DejaVu Sans")


def add_arrow(ax, x1, y1, x2, y2):
    arr = FancyArrowPatch(
        (x1, y1), (x2, y2),
        arrowstyle="->,head_length=4,head_width=3",
        linewidth=0.9, color=COL_BORDER,
        shrinkA=0, shrinkB=0,
    )
    ax.add_patch(arr)


def main() -> None:
    # Canvas: 6 in wide, 8 in tall  --> 300 dpi
    fig, ax = plt.subplots(figsize=(6.0, 8.0), dpi=300)
    ax.set_xlim(0, 10)
    ax.set_ylim(0, 14)
    ax.set_axis_off()

    # Phase headers (left rail)
    add_header(ax, 0.05, 12.7, "IDENTIFICATION")
    add_header(ax, 0.05,  9.7, "SCREENING")
    add_header(ax, 0.05,  6.4, "ELIGIBILITY")
    add_header(ax, 0.05,  2.4, "INCLUDED")

    # IDENTIFICATION
    add_box(ax, 1.6, 11.9, 3.8, 1.3,
            "Records identified from\ndatabases (PubMed, multi-strand)\nn = 5 516 hits")
    add_box(ax, 5.7, 11.9, 3.8, 1.3,
            "Records identified from\nother sources\n(hand-search, snowballing)\nn = 15")

    # SCREENING
    add_box(ax, 1.6,  9.0, 3.8, 1.2,
            "Records after duplicates\nremoved\nn = 146")
    add_box(ax, 5.7,  9.0, 3.8, 1.2,
            "Records excluded (title/abstract)\nOff-topic\nn = 9", fillcolor=COL_BOX_EXC)

    # ELIGIBILITY
    add_box(ax, 1.6,  5.5, 3.8, 1.2,
            "Full-text articles assessed\nfor eligibility\nn = 137")
    add_box(ax, 5.7,  4.5, 3.8, 2.4,
            "Full-text excluded\nwith reasons (n = 104):\n"
            "- Trials / cohorts: 54\n"
            "- Surgical-technique originals: 31\n"
            "- Imaging / marker originals: 26\n"
            "- Pathology originals: 12\n"
            "- Guidelines / expert reviews: 28\n"
            "- Other tumours: 72\n"
            "- Radiotherapy originals: 8\n"
            "- Prognosis cohorts: 7\n"
            "- Breast-axilla originals: 20",
            fillcolor=COL_BOX_EXC, fontsize=7.5)

    # INCLUDED
    add_box(ax, 1.6,  1.7, 3.8, 1.3,
            "Studies included in\nqualitative synthesis (SR/MA)\nn = 23", weight="bold")
    add_box(ax, 5.7,  1.7, 3.8, 1.3,
            "Studies included in\nquantitative synthesis\nn = 0\n(umbrella, JBI: no re-pooling)")

    # Arrows
    add_arrow(ax, 3.5, 11.9, 3.5, 10.2)   # databases -> dedup
    add_arrow(ax, 7.6, 11.9, 5.4,  9.6)   # other -> dedup (diagonal)
    add_arrow(ax, 5.4,  9.6, 5.7,  9.6)   # dedup -> exc T/A
    add_arrow(ax, 3.5,  9.0, 3.5,  6.7)   # dedup -> full-text
    add_arrow(ax, 5.4,  6.1, 5.7,  6.1)   # full-text -> exc F/T
    add_arrow(ax, 3.5,  5.5, 3.5,  3.0)   # full-text -> included
    add_arrow(ax, 5.4,  2.35, 5.7, 2.35)  # included -> quantitative

    # Footer
    ax.text(0.05, 0.4,
            "PRISMA 2020 (Page MJ et al., BMJ 2021;372:n71). Counts verified against INDICE_MAESTRO.csv.",
            ha="left", va="center", fontsize=6.5, color="#666666",
            family="DejaVu Sans", style="italic")

    fig.tight_layout(pad=0.3)
    fig.savefig(OUT_PNG, dpi=300, bbox_inches="tight", facecolor="white")
    print(f"Saved {OUT_PNG}")


if __name__ == "__main__":
    main()
