#!/usr/bin/env python3
"""Draw the half-hour profile as a hand-written SVG in the site's palette.

Usage: ~/.venv/bin/python chart.py  -> site/public/images/gold-by-the-half-hour.svg (+ a PNG preview in /tmp)
One series (typical move on the median day per half hour, USD/oz), so no legend; bars are thin,
rounded at the data end, square at the baseline; grid is a hairline one step off the surface.
"""
import os

import pandas as pd

HERE = os.path.dirname(os.path.abspath(__file__))
OUT = os.path.join(HERE, "..", "..", "site", "public", "images", "gold-by-the-half-hour.svg")

GROUND, RULE, DIM, TEXT, ACCENT = "#0f1120", "#262a44", "#a9a2c6", "#e8e3d8", "#f2b544"
W, H = 720, 400
L, R, T, B = 52, 12, 28, 78          # margins
PW, PH = W - L - R, H - T - B

bins = pd.read_csv(os.path.join(HERE, "bins.csv"))
col = "median_day_move_usd"
ymax = 20.0
n = len(bins)
slot = PW / n
bar_w = min(24, slot - 3)

def y(v):
    return T + PH - (v / ymax) * PH

def x(i):
    return L + i * slot + (slot - bar_w) / 2

parts = [
    f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H}" width="{W}" height="{H}" role="img" aria-labelledby="t d" '
    f'font-family="JetBrains Mono, ui-monospace, Menlo, monospace" font-size="11">',
    '<title id="t">Typical movement of gold per half hour of the day, New York time, on the median weekday, USD per ounce</title>',
    '<desc id="d">' + "Bars for each half hour from 00:00 to 23:30 New York. " + "; ".join(
        f"{r.ny_time}: {r[col]:.1f}" if r.days > 80 else f"{r.ny_time}: no data, broker break"
        for _, r in bins.iterrows()) + ". Source: one broker's gold quotes, 2026-01 to 2026-08, 170 weekdays.</desc>",
    f'<rect width="{W}" height="{H}" fill="{GROUND}"/>',
]
# grid + y labels
for v in (0, 5, 10, 15, 20):
    parts.append(f'<line x1="{L}" y1="{y(v):.1f}" x2="{W - R}" y2="{y(v):.1f}" stroke="{RULE}" stroke-width="1"/>')
    parts.append(f'<text x="{L - 8}" y="{y(v) + 4:.1f}" fill="{DIM}" text-anchor="end">{v}</text>')
parts.append(f'<text x="{L - 8}" y="{T - 10}" fill="{DIM}" text-anchor="end">USD</text>')

# bars
for i, r in bins.iterrows():
    if r.days <= 80:   # the broker's break: present on 15 days only, not comparable
        continue
    v = float(r[col])
    x0, y0, y1 = x(i), y(v), y(0)
    rr = min(4, bar_w / 2, (y1 - y0) / 2)
    parts.append(
        f'<path d="M{x0:.1f},{y1:.1f} V{y0 + rr:.1f} a{rr},{rr} 0 0 1 {rr},-{rr} H{x0 + bar_w - rr:.1f} '
        f'a{rr},{rr} 0 0 1 {rr},{rr} V{y1:.1f} Z" fill="{ACCENT}"/>')
    if r.ny_time in ("09:30", "10:00", "21:00", "23:30"):
        parts.append(f'<text x="{x0 + bar_w / 2:.1f}" y="{y0 - 5:.1f}" fill="{TEXT}" text-anchor="middle">{v:.0f}</text>')


# x axis: every 3 hours
for i, r in bins.iterrows():
    if r.ny_time.endswith(":00") and int(r.ny_time[:2]) % 3 == 0:
        parts.append(f'<text x="{x(i) + bar_w / 2:.1f}" y="{y(0) + 16}" fill="{DIM}" text-anchor="middle">{r.ny_time}</text>')

# event labels, second row, tied to the bin they name
events = [("03:00", "London open", "middle"), ("08:30", "US data", "end"), ("10:00", "London PM fix", "start"),
          ("17:00", "close", "middle"), ("20:00", "Tokyo", "end"), ("21:00", "Shanghai", "start")]
for t, label, anchor in events:
    i = bins.index[bins.ny_time == t][0]
    cx = x(i) + bar_w / 2
    parts.append(f'<line x1="{cx:.1f}" y1="{y(0) + 22}" x2="{cx:.1f}" y2="{y(0) + 30}" stroke="{RULE}" stroke-width="1"/>')
    tx = cx - 4 if anchor == "end" else cx + 4 if anchor == "start" else cx
    parts.append(f'<text x="{tx:.1f}" y="{y(0) + 42}" fill="{DIM}" text-anchor="{anchor}" font-size="10">{label}</text>')

parts.append(f'<text x="{L}" y="{H - 8}" fill="{DIM}" font-size="10">'
             'Median-day realised variance per half hour, bid. One broker, weekdays 2026-01 to 2026-08, New York time.</text>')
parts.append("</svg>")
os.makedirs(os.path.dirname(OUT), exist_ok=True)
open(OUT, "w").write("\n".join(parts) + "\n")
print("wrote", os.path.normpath(OUT))

try:
    import pymupdf
    pymupdf.open(OUT)[0].get_pixmap(dpi=144).save("/tmp/gold-by-the-half-hour.png")
    print("preview /tmp/gold-by-the-half-hour.png")
except Exception as e:  # preview only
    print("no preview:", e)
