#!/usr/bin/env python3
"""
BidBrain monthly learning run, Phase 3.

Reads the previous month's sold cars from Clickdealer (the sold vehicles report
joined to the sales margins report, plus each car's supplier from its own
page), stores them in sales_history, and rebuilds the learned_models figures
that drive the history notes on the daily cards.

Run by launchd on the 10th of each month (after the month's accounts settle),
or by hand:

  python3 monthly_run.py                 ingest last month, rebuild learning
  python3 monthly_run.py --month 2026-05 ingest one named month
  python3 monthly_run.py --backfill 12   ingest the last N whole months

Reads reports only. Never changes anything on Clickdealer, never bids.
"""

import sys
import datetime

from playwright.sync_api import sync_playwright

from bidbrain import db
from bidbrain.readers import clickdealer


def _prev_month(today=None):
    today = today or datetime.date.today()
    first = today.replace(day=1)
    last_month = first - datetime.timedelta(days=1)
    return last_month.year, last_month.month


def _months_back(n, today=None):
    """The last n whole months, oldest first."""
    y, m = _prev_month(today)
    out = []
    for _ in range(n):
        out.append((y, m))
        m -= 1
        if m == 0:
            y, m = y - 1, 12
    return list(reversed(out))


def ingest(year, month):
    label = f"{year}-{month:02d}"
    print(f"Reading sold cars for {label}")
    with sync_playwright() as p:
        rows = clickdealer.read_sales_month(
            p, year, month,
            progress=lambda i, n: print(f"  supplier {i}/{n}", end="\r"))
    print()
    n = db.record_sales_history(rows)
    with_margin = sum(1 for r in rows if r.get("margin") is not None)
    with_source = sum(1 for r in rows if r.get("source"))
    print(f"  {n} sold cars stored ({with_margin} with margin, {with_source} with supplier)")
    return n


def main():
    db.init_db()
    months = []
    if "--backfill" in sys.argv:
        i = sys.argv.index("--backfill")
        n = int(sys.argv[i + 1]) if i + 1 < len(sys.argv) else 12
        months = _months_back(n)
    elif "--month" in sys.argv:
        i = sys.argv.index("--month")
        y, m = sys.argv[i + 1].split("-")
        months = [(int(y), int(m))]
    else:
        months = [_prev_month()]

    total = 0
    failures = []
    for y, m in months:
        try:
            total += ingest(y, m)
        except Exception as e:
            # Fail loudly per month but keep going so one bad month does not
            # lose the rest of a backfill.
            print(f"  FAILED {y}-{m:02d}: {e}")
            failures.append(f"{y}-{m:02d}")

    n_models = db.rebuild_learned_models()
    print(f"\nLearning rebuilt: {n_models} models from the sold history.")
    if failures:
        print(f"ATTENTION: {len(failures)} month(s) failed and need a re run: {', '.join(failures)}")
        sys.exit(1)


if __name__ == "__main__":
    main()
