"""House chart helper for In Motion Automation reports and decks (deck kit Rev 2, 4 Nov 2026).

Import it from a pack's figures/make_figures.py:

    import sys; sys.path.insert(0, "<path to deck-kit>/figures")
    from house_figures import plt, mticker, PAGE_W, INK, NAVY, DEEP, MID, SKY, MUTED, LINE, CYAN, STONE, clean, finish

Rules it carries (from GUIDE.md, Dataviz):
- Geist on chart text; the cool-lane palette; one cyan or navy highlight, never rainbow fills.
- Every chart gets a finding title above (a full sentence that states the result) and a
  source note below (sources, sample, what is made up), both drawn by finish().
- Size for the page: PAGE_W is the US Letter text width; the deck embeds the same PNG.
- Saved as SVG, PNG at 200 dpi and vector PDF. Never redraw a chart with different numbers.
Run this file alone to draw the example chart: python3 house_figures.py
"""
import textwrap
from pathlib import Path

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt  # noqa: E402
import matplotlib.ticker as mticker  # noqa: E402
from matplotlib import font_manager  # noqa: E402

HERE = Path(__file__).resolve().parent
plt.style.use(str(HERE / "ima-research.mplstyle"))
for w in ("400", "500", "600"):
    f = HERE / "fonts" / f"Geist-{w}.ttf"
    if f.exists():
        font_manager.fontManager.addfont(str(f))

INK = "#10151C"
NAVY = "#0B1622"
DEEP = "#6A8AA3"
MID = "#9BB3C7"
SKY = "#C5D4E2"
MUTED = "#5A6572"
LINE = "#CDD5DD"
CYAN = "#4EC3E0"
STONE = "#EEF2F5"

plt.rcParams.update({
    "font.family": "Geist",
    "font.size": 9,
    "xtick.color": MUTED,
    "ytick.major.size": 0,
    "svg.fonttype": "path",
    "pdf.fonttype": 42,
    "text.parse_math": False,  # "$" is a dollar sign, never math mode
})

PAGE_W = 6.5  # inches: text width on US Letter with 1in margins


def wrap(text, width_in, fs):
    chars = max(20, int(width_in * 72 / (fs * 0.50)))
    return "\n".join(textwrap.wrap(text, chars))


def clean(ax, grid="x"):
    """Light grid on one axis, no left spine, pale bottom spine."""
    ax.grid(axis=grid, color=LINE, linewidth=0.5)
    ax.set_axisbelow(True)
    ax.spines["left"].set_visible(False)
    ax.spines["bottom"].set_color(LINE)


def finish(fig, out_dir, name, title, note, title_fs=10.5, note_fs=7.2):
    """Finding title above and source note below the plot block, then save SVG, PNG, PDF."""
    fig.canvas.draw()
    r = fig.canvas.get_renderer()
    boxes = [ax.get_tightbbox(r) for ax in fig.axes if ax.get_visible()]
    inv = fig.transFigure.inverted()
    x0 = min(inv.transform((b.x0, b.y0))[0] for b in boxes)
    x1 = max(inv.transform((b.x1, b.y1))[0] for b in boxes)
    y0 = min(inv.transform((b.x0, b.y0))[1] for b in boxes)
    y1 = max(inv.transform((b.x1, b.y1))[1] for b in boxes)
    w_in = (x1 - x0) * fig.get_figwidth()
    h = fig.get_figheight()
    fig.text(x0, y1 + 0.10 / h, wrap(title, w_in, title_fs), ha="left", va="bottom",
             fontsize=title_fs, fontweight=600, color=INK, linespacing=1.25)
    fig.text(x0, y0 - 0.08 / h, wrap(note, w_in, note_fs), ha="left", va="top",
             fontsize=note_fs, color=MUTED, linespacing=1.35)
    out_dir = Path(out_dir)
    for ext, kw in (("svg", {}), ("png", {"dpi": 200}), ("pdf", {})):
        fig.savefig(out_dir / f"{name}.{ext}", bbox_inches="tight", pad_inches=0.08, **kw)
    plt.close(fig)


def example():
    """EXAMPLE DATA, made up to show the style. Replace with a source-backed series."""
    rows = [("Item A", 62), ("Item B", 59), ("Item C", 58), ("Item D", 48), ("Item E", 46)]
    fig, ax = plt.subplots(figsize=(PAGE_W, 2.4))
    for i, (lab, v) in enumerate(rows):
        ax.barh(-i, v, height=0.6, color=NAVY if i == 0 else DEEP, zorder=2)
        ax.text(v + 1, -i, f"{v}%", va="center", fontsize=7.6, color=INK)
    ax.set_yticks([-i for i in range(len(rows))])
    ax.set_yticklabels([r[0] for r in rows], fontsize=7.8, color=INK)
    ax.set_xlim(0, 100)
    ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda v, _p: f"{int(v)}%"))
    ax.set_xlabel("Share of cases, percent", fontsize=8, color=MUTED)
    clean(ax)
    finish(fig, HERE, "example-house-chart",
           "The title states the finding as a full sentence: Item A leads at 62%, "
           "three points ahead of the next",
           "Example data, made up to show the style. The note names every source, the sample "
           "and anything made up, in one or two lines.")


if __name__ == "__main__":
    example()
    print("wrote example-house-chart.svg/png/pdf")
