"""Reproduce the article's synthetic reference results; no network or vendor writes."""
import csv, json
from datetime import datetime, timedelta, timezone
from pathlib import Path
ROOT = Path(__file__).parent
base = datetime(2026, 9, 1, 12, tzinfo=timezone.utc)
# Eight registered people in seven workspaces. Each row is a committed action.
journeys = {
    'A': [('signup', 0), ('project_created', 1), ('teammate_invited', 2)],
    'B': [('signup', 0), ('project_created', 1)],
    'C': [('signup', 0)],
    'D': [('signup', 0), ('project_created', 1), ('teammate_invited', 8)],
    'E': [('signup', 0), ('teammate_invited', 1), ('project_created', 2)],
    'F': [('signup', 0), ('project_created', 1), ('teammate_invited', 2)],
    'G': [('signup', 0), ('project_created', 1)],
    'H': [('signup', 0.25), ('teammate_invited', 2)],
}
rows = []
for user, actions in journeys.items():
    for n, (event, day) in enumerate(actions):
        rows.append({'event_id': f'{user}-{n}', 'user_id': user, 'workspace_id': 'GH' if user in 'GH' else user, 'event': event, 'timestamp': (base + timedelta(days=day)).isoformat(), 'environment': 'fixture', 'schema_version': 1})
rows.append(next(row.copy() for row in rows if row['event_id'] == 'F-1'))
with (ROOT / 'activation-fixture.csv').open('w') as file:
    writer = csv.DictWriter(file, fieldnames=list(rows[0]))
    writer.writeheader(); writer.writerows(rows)
unique = list({row['event_id']: row for row in rows}.values())
def funnel(grain, days):
    groups = {}
    for row in unique:
        groups.setdefault(row[grain], []).append(row)
    counts = [0, 0, 0]
    completed = []
    for identity, events in groups.items():
        events.sort(key=lambda row: row['timestamp'])
        start = next(datetime.fromisoformat(row['timestamp']) for row in events if row['event'] == 'signup')
        previous = start
        reached = 0
        for name in ['signup', 'project_created', 'teammate_invited']:
            matches = [datetime.fromisoformat(row['timestamp']) for row in events if row['event'] == name and previous <= datetime.fromisoformat(row['timestamp']) <= start + timedelta(days=days)]
            if not matches: break
            previous = min(matches); counts[reached] += 1; reached += 1
        if reached == 3: completed.append(identity)
    return {'steps': counts, 'completed': completed, 'conversion_percent': round(counts[2] / counts[0] * 100, 2)}
result = {'raw_rows': len(rows), 'deduplicated_rows': len(unique), **{f'{grain}_{days}d': funnel(grain, days) for grain in ['user_id', 'workspace_id'] for days in [7, 14]}}
assert result['user_id_7d']['steps'] == [8, 6, 2]
assert result['workspace_id_7d']['steps'] == [7, 6, 3]
assert result['user_id_14d']['steps'] == [8, 6, 3]
assert result['workspace_id_14d']['steps'] == [7, 6, 4]
(ROOT / 'fixture-results.json').write_text(json.dumps(result, indent=2) + '\n')
print(json.dumps(result, indent=2))
