"""Generate a Markwhen timeline (.mw) for the TEC retrospective.

Inputs:
  data/onchain/cv_proposals.csv   (id, block, amount_requested, link, status, executed_block)
  data/onchain/cv_proposal_categories.json  (id -> category tag, optional)

Output:
  output/tec_retrospective.mw

Anchoring: Gnosis block 20086948 == 2022-01-27 (CV proposal #1 per synthesis),
block time ~5.0s. Close enough for a retrospective timeline.
"""
from __future__ import annotations

import csv
import json
from datetime import datetime, timedelta, timezone
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
PROPOSALS = ROOT / "data" / "onchain" / "cv_proposals.csv"
CATEGORIES = ROOT / "data" / "onchain" / "cv_proposal_categories.json"
OUT = ROOT / "output" / "tec_retrospective.mw"

ANCHOR_BLOCK = 20086948
ANCHOR_DATE = datetime(2022, 1, 27, tzinfo=timezone.utc)
GNOSIS_BLOCK_SECONDS = 5.0


def block_to_date(block: int) -> datetime:
    delta = (block - ANCHOR_BLOCK) * GNOSIS_BLOCK_SECONDS
    return ANCHOR_DATE + timedelta(seconds=delta)


def load_categories() -> dict[str, str]:
    if not CATEGORIES.exists():
        return {}
    raw = json.loads(CATEGORIES.read_text())
    if isinstance(raw, dict):
        return {str(k): str(v) for k, v in raw.items()}
    return {}


HEADER = """---
title: Token Engineering Commons — Retrospective
view: timeline
timezone: UTC
#hatch: blue
#abc: orange
#cv: green
#shock: red
#migration: purple
#shutdown: gray
---

// Generated by scripts/gen_timeline.py
// Edit macro events here; CV proposal section is auto-appended.

section Origins #hatch
2021-02-01 / 2021-08-11: Trusted Seed recruitment & Hatch prep
  210 backers onboarded via Commons Stack Hatch app
2021-08-11: Hatch closed — 1,571,224 wxDAI raised from 210 backers #hatch
  https://medium.com/token-engineering-commons/the-hatch-was-successful-2443cd07cbb0
2021-08-12 / 2022-01-26: Commons Configuration Dashboard — 40 parameter proposals, 2 rounds of voting #hatch
endSection

section ABC & Markets #abc
2022-01-25: 500K whale purchase — 499,803 xDAI (46.5% of all ABC buy volume, ever) #abc
  wallet 0xf5dcd98a...12f35497 · entry tribute ~109,957 xDAI
2022-01-27: ABC live on Gnosis Chain; first CV proposal submitted #abc #cv
2022-05-09: Terra/Luna collapse — first exogenous shock #shock
2022-11-08: FTX collapse — second exogenous shock, crypto winter deepens #shock
2023-12-01: ABC price bottom — 0.36 xDAI (-88% from peak of 2.94) #abc
endSection

section Treasury & Migration #migration
2023-12-15: Migration to Optimism; CV replaced by multisig coordination #migration
  reserve currency: xDAI → rETH
  https://forum.tecommons.org/t/and-we-are-live-on-op-mainnet/1324
2024-01-01 / 2025-11-04: Post-migration draw-down era (manual allocations)
2025-04-01: Q1 2025 Progress Report — tribute revenue $3,614/qtr vs $42,244/qtr opex #shutdown
  https://forum.tecommons.org/t/tec-q1-2025-progress-report/1472
2025-11-04: TEC shutdown proposal formally approved #shutdown
  https://forum.tecommons.org/t/tec-shutdown-proposal/1520
endSection

"""


def build_cv_section(rows: list[dict], cats: dict[str, str]) -> str:
    lines = ["section Conviction Voting Proposals #cv", ""]
    for row in rows:
        pid = row["id"]
        try:
            block = int(row["block"])
        except (TypeError, ValueError):
            continue
        created = block_to_date(block)
        executed = None
        if row.get("executed_block"):
            try:
                executed = block_to_date(int(row["executed_block"]))
            except ValueError:
                pass
        amount = row.get("amount_requested") or "0"
        try:
            amount_f = float(amount)
        except ValueError:
            amount_f = 0.0
        status = (row.get("status") or "").lower()
        title = (row.get("link") or f"Proposal #{pid}").strip() or f"Proposal #{pid}"
        title = title.replace("\n", " ")[:90]
        cat = cats.get(str(pid), "")
        tags = [f"#{status}"] if status else []
        if cat:
            tags.append(f"#{cat.lower().replace(' ', '_')}")
        tag_str = " " + " ".join(tags) if tags else ""
        if executed and status == "executed":
            rng = f"{created:%Y-%m-%d} / {executed:%Y-%m-%d}"
        else:
            rng = f"{created:%Y-%m-%d}"
        amount_note = f" — {amount_f:,.0f} TEC" if amount_f > 0 else ""
        lines.append(f"{rng}: #{pid} {title}{amount_note}{tag_str}")
    lines.append("endSection")
    return "\n".join(lines) + "\n"


def main() -> None:
    rows = list(csv.DictReader(PROPOSALS.open()))
    cats = load_categories()
    body = HEADER + build_cv_section(rows, cats)
    OUT.parent.mkdir(exist_ok=True)
    OUT.write_text(body)
    print(f"Wrote {OUT} ({len(rows)} proposals)")


if __name__ == "__main__":
    main()
