#!/usr/bin/env python3
"""Daily journal pre-population.

Writes 01-journal/<YYYY-MM-DD>.md with:
  - Date header (frontmatter)
  - Overnight moves table for the headline universe (last close + 1d %)
  - Today's calendar events (Tier 1/2/structural) per 07-calendar/macro-book.ics
  - Per-instrument assessment checklist stub (one block per headline ticker)
  - Empty placeholders for the user's Macro/Positions/Flows journal input

The user then edits the file in Obsidian to add their own commentary.
"""
from __future__ import annotations

import argparse
import sys
from datetime import date, datetime
from pathlib import Path
from zoneinfo import ZoneInfo

VAULT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(VAULT / "scripts"))

from data.prices import headline_metrics  # noqa: E402
from data.calendar_parse import events_for_date  # noqa: E402

JOURNAL_DIR = VAULT / "01-journal"


def fmt_change(pct: float | None) -> str:
    if pct is None:
        return "—"
    sign = "+" if pct >= 0 else ""
    return f"{sign}{pct:.2f}%"


def render_overnight_table(metrics: list[dict]) -> str:
    lines = [
        "| Ticker | Name | Last | 1d % | 5d % | 1m % |",
        "|---|---|---:|---:|---:|---:|",
    ]
    for m in metrics:
        lines.append(
            f"| {m['ticker']} | {m.get('name', '')} | {m['last']} | "
            f"{fmt_change(m['chg_1d_pct'])} | {fmt_change(m['chg_5d_pct'])} | "
            f"{fmt_change(m['chg_1m_pct'])} |"
        )
    return "\n".join(lines)


def render_calendar(today_events: list[dict], target_date: date) -> str:
    if not today_events:
        return f"_No Tier 1/2/structural events scheduled for {target_date}._"
    tz = ZoneInfo("Europe/Zurich")
    lines = [
        "| Time (Zurich) | Tier | Event | ID |",
        "|---|---|---|---|",
    ]
    for e in today_events:
        zurich = e["dtstart_utc"].astimezone(tz)
        t = zurich.strftime("%H:%M")
        tier = f"T{e['tier']}" if isinstance(e["tier"], int) else (str(e["tier"]).upper() if e["tier"] else "—")
        sm = e["summary"]
        for tag in ("[T1]", "[T2]", "[STRUCTURAL]"):
            sm = sm.replace(tag, "").strip()
        lines.append(f"| {t} | {tier} | {sm} | `{e['id']}` |")
    return "\n".join(lines)


def render_journal(target_date: date, metrics: list[dict], today_events: list[dict]) -> str:
    date_str = target_date.isoformat()
    weekday = target_date.strftime("%A")
    frontmatter = (
        "---\n"
        f"type: daily-journal\n"
        f"date: {date_str}\n"
        f"weekday: {weekday}\n"
        f"status: prepopulated\n"
        f"generated: {datetime.now().isoformat(timespec='seconds')}\n"
        f"location: Zurich, Switzerland (Europe/Zurich)\n"
        "---\n"
    )
    title = f"# Daily Journal — {date_str} ({weekday})\n"
    # As-of: most recent date present across all tickers
    as_of_dates = [m["as_of"] for m in metrics if m.get("as_of")]
    as_of_str = max(as_of_dates) if as_of_dates else "latest available"
    parts = [
        frontmatter,
        title,
        "## Overnight / last-close snapshot (headline universe)\n",
        f"_As of: {as_of_str} (most recent close across universe; some tickers may be a session behind due to local market holidays)_\n",
        render_overnight_table(metrics),
        "",
        "## Today's calendar (Europe/Zurich)\n",
        render_calendar(today_events, target_date),
        "",
        "## Macro (your read)\n",
        "_Write here._\n",
        "## Positions (your read)\n",
        "_Write here._\n",
        "## Flows / news (your read)\n",
        "_Write here._\n",
        "## Pre-event research links\n",
        "_Link to 03-research/event/<id>.md previews filled in for today's Tier 1 events._\n",
        "## Assessment checklist (per [[../../00-methodology/decision-process]])\n",
        "- [ ] Reviewed overnight price action in headline universe above",
        "- [ ] Reviewed today's calendar — Tier 1 events have pre-event research in `03-research/event/`",
        "- [ ] COT positioning check: see Friday `cot-friday` release if Friday",
        "- [ ] Cross-asset: bucket siblings confirming the read (see [[../../00-methodology/risk-framework]])",
        "- [ ] Not inside Tier 1 event blackout window (60 min before release)",
        "- [ ] Risk 25-75bp of NAV at stop, portfolio open-risk ≤ 250bp",
        "- [ ] Invalidation fact drafted (not a price) for any open consideration",
        "- [ ] No duplication of an existing book view\n",
        "## Per-instrument notes\n",
        "_For each instrument that touched a level or printed a catalyst today, link to the per-instrument note in `06-universe/traded/` and update the assessment checklist there._\n",
        "## End-of-day close review\n",
        "_Fill in after 22:00 Zurich: full-universe closes, % changes, attribution._\n",
    ]
    return "\n".join(parts)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--date", default=None,
        help="Target date YYYY-MM-DD (default: today in Europe/Zurich)"
    )
    parser.add_argument(
        "--force", action="store_true",
        help="Overwrite existing journal file"
    )
    args = parser.parse_args()
    if args.date:
        target = date.fromisoformat(args.date)
    else:
        target = datetime.now(ZoneInfo("Europe/Zurich")).date()
    out_path = JOURNAL_DIR / f"{target.isoformat()}.md"
    if out_path.exists() and not args.force:
        print(f"EXISTS: {out_path}  (use --force to overwrite)")
        return 0
    print(f"Fetching headline metrics for {target}...")
    metrics = headline_metrics()
    print(f"  {len(metrics)} tickers")
    print(f"Fetching today's calendar events...")
    events = events_for_date(target)
    print(f"  {len(events)} events")
    body = render_journal(target, metrics, events)
    out_path.write_text(body)
    print(f"Wrote: {out_path}  ({len(body)} bytes)")
    return 0


if __name__ == "__main__":
    sys.exit(main())
