"""The demo file for "Bring your own CSV": a subscription dataset with four shortcuts in it.

    python data/make_demo_csv.py        # writes web/demo.csv

Planted problems: `customer_id` was assigned after sorting by the label; `refund_amount`
is only ever filled in for customers who left; `signup_date` carries a strong drift in the
label (the last months are mostly leavers); and 90 rows are near-copies of other rows.
"""
from __future__ import annotations

import csv
import os
import sys

import numpy as np

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ROOT)


def make(seed=11, n=510, ndup=90):
    rng = np.random.default_rng(seed)
    day = np.sort(rng.integers(0, 365, n))
    plan = rng.choice(["basic", "plus", "pro"], n, p=[0.5, 0.35, 0.15])
    age = rng.integers(18, 75, n)
    sessions = rng.poisson(12, n)
    tickets = rng.poisson(0.7, n)
    tenure = rng.integers(1, 48, n)
    z = lambda x: (x - x.mean()) / x.std()  # noqa: E731
    drift = np.where(day > 280, 2.4, 0.0)
    logit = -0.8 - 0.5 * z(sessions) + 0.5 * z(tickets) - 0.4 * z(tenure) + drift
    y = (rng.random(n) < 1 / (1 + np.exp(-logit))).astype(int)
    refund = np.where(y == 1, np.round(rng.uniform(5, 60, n), 2), 0.0)
    refund[(y == 1) & (rng.random(n) < 0.05)] = 0.0
    order = np.argsort(y, kind="stable")
    cid = np.empty(n, dtype=int)
    cid[order] = 50001 + np.arange(n)
    rows = []
    for i in range(n):
        d = np.datetime64("2025-01-01") + np.timedelta64(int(day[i]), "D")
        rows.append([cid[i], str(d), plan[i], int(age[i]), int(sessions[i]), int(tickets[i]), int(tenure[i]), float(refund[i]), "yes" if y[i] else "no"])
    for k in rng.integers(0, n, ndup):           # near-copies: same customer, re-exported with a tiny change
        r = list(rows[k])
        r[0] = int(r[0]) + 10000
        r[4] = int(r[4]) + int(rng.integers(0, 2))
        rows.append(r)
    perm = rng.permutation(len(rows))
    rows = [rows[i] for i in perm]
    header = ["customer_id", "signup_date", "plan", "age", "sessions_30d", "support_tickets", "tenure_months", "refund_amount", "left"]
    return header, rows


def main():
    header, rows = make()
    path = os.path.join(ROOT, "web", "demo.csv")
    with open(path, "w", newline="", encoding="utf-8") as f:
        w = csv.writer(f)
        w.writerow(header)
        w.writerows(rows)
    print(path, os.path.getsize(path), "bytes", len(rows), "rows")


if __name__ == "__main__":
    main()
