"""Demo engine: proves the loop end to end. Reads the uploaded schedule,
simulates the pipeline stages with believable timing, writes a real summary
workbook, detailed workbook, and flags JSON. Replaced by the real engine."""
from __future__ import annotations
import json, random, time
from pathlib import Path
import pandas as pd

STAGES = [
    (8,  "Checking your file",       "Reading columns and dates"),
    (30, "Matching evidence",        "Searching historical broadcasts"),
    (75, "Estimating audiences",     ""),
    (90, "Running safety checks",    "Comparing against market sizes"),
    (99, "Preparing your reports",   "Formatting workbooks"),
]

def run_pipeline(*, upload_path: Path, exports_dir: Path, run_id: str, on_progress):
    df = pd.read_excel(upload_path)
    n = max(1, len(df))
    on_progress(3, "Checking your file", f"{n:,} rows found")
    time.sleep(1.0)
    for target, stage, detail in STAGES:
        start = int(target * 0.55)
        for pct in range(start, target + 1, 3):
            d = detail
            if stage == "Estimating audiences":
                row = min(n, max(1, int(n * pct / 100)))
                d = f"row {row:,} of {n:,}"
            on_progress(pct, stage, d)
            time.sleep(0.35)
    # demo outputs
    rng = random.Random(run_id)
    out = df.copy()
    out["estimated_ama_000"] = [round(rng.uniform(5, 900), 1) for _ in range(len(out))]
    out["confidence"] = [rng.choice(["Very High", "High", "Medium", "Low"]) for _ in range(len(out))]
    flagged = out.sample(min(3, len(out)), random_state=1) if len(out) else out
    summary = exports_dir / f"{run_id}_summary.xlsx"
    detailed = exports_dir / f"{run_id}_detailed.xlsx"
    out.head(50).to_excel(summary, index=False)
    out.to_excel(detailed, index=False)
    flags = [{"row": int(i) + 2,
              "channel": str(r.get("channel_name", r.iloc[0] if len(r) else "Channel")),
              "country": str(r.get("country_name", "Market")),
              "programme": str(r.get("programme_name", r.get("event_name", "Programme"))),
              "ama": r["estimated_ama_000"],
              "why": "Estimate is above 15% of this market's TV universe"}
             for i, r in flagged.iterrows()]
    (exports_dir / f"{run_id}_flags.json").write_text(json.dumps(flags))

    # demo chart data — same shape the real engine emits, so results.php works today
    tiers = ["Same channel", "Same teams", "Same market", "Cross-market", "Time-slot history"]
    tier_pick = [rng.choice(tiers, p=[.35, .2, .2, .15, .1]) for _ in range(len(out))]
    countries = list(out.get("country_name", pd.Series(["India", "UAE", "UK"])).unique()) or ["India"]
    bins_labels = ["0-5k","5-20k","20-50k","50-100k","100-250k","250-500k","500k-1M","1M-5M","5M+"]
    edges = [0,5,20,50,100,250,500,1000,5000,1e12]
    hist = pd.cut(out["estimated_ama_000"], bins=edges, labels=bins_labels, right=False).value_counts().reindex(bins_labels).fillna(0)
    conf_band = pd.cut(out["confidence"].map({"Very High":95,"High":80,"Medium":68,"Low":45}),
                       bins=[0,60,75,90,100], labels=["Low","Medium","High","Very High"]).value_counts()
    tier_counts = pd.Series(tier_pick).value_counts().reindex(tiers).fillna(0)
    top_markets = out.assign(_c=[rng.choice(countries) for _ in range(len(out))]).groupby("_c")["estimated_ama_000"].sum().sort_values(ascending=False).head(8)
    table = out.assign(country_name=[rng.choice(countries) for _ in range(len(out))],
                       channel_name=out.get("channel_name", pd.Series(["Sports 1"]*len(out))),
                       event_name=out.get("event_name", pd.Series(["Event"]*len(out))),
                       telecast_type=out.get("telecast_type", pd.Series(["LIVE"]*len(out))),
                       strategy=tier_pick, interval80_low=(out["estimated_ama_000"]*0.8).round(1),
                       interval80_high=(out["estimated_ama_000"]*1.25).round(1), flag="")
    table.loc[table.index.isin(flagged.index), "flag"] = "REVIEW_ABOVE_15PCT_TVU"
    cols = ["event_name","country_name","channel_name","telecast_type","estimated_ama_000",
           "interval80_low","interval80_high","confidence","strategy","flag"]
    chart_payload = {
        "kpi": {"rows_total": n, "rows_estimated": n,
               "median_ama": round(float(out["estimated_ama_000"].median()), 1),
               "mean_confidence": 78.4, "flagged": len(flags)},
        "distribution": {"labels": bins_labels, "values": [int(v) for v in hist.tolist()]},
        "confidence_bands": {"labels": ["Very High","High","Medium","Low"],
                             "values": [int(conf_band.get(k,0)) for k in ["Very High","High","Medium","Low"]]},
        "tiers": {"labels": tiers, "values": [int(v) for v in tier_counts.tolist()]},
        "top_markets": {"labels": [str(x) for x in top_markets.index.tolist()],
                        "values": [round(float(v),1) for v in top_markets.tolist()]},
        "flags": {"labels": ["None","REVIEW_ABOVE_15PCT_TVU"], "values": [n-len(flags), len(flags)]},
        "rows": table[cols].to_dict(orient="records"),
    }
    (exports_dir / f"{run_id}_chartdata.json").write_text(json.dumps(chart_payload))

    return {"rows_total": n, "rows_estimated": n, "rows_flagged": len(flags),
            "summary_path": summary, "detailed_path": detailed}
