"""Reproduce the dated catalogue comparison locally; no network or model calls.
Usage: python3 reproduce.py [paired-snapshots.json] [output-directory]
Missing price fields remain None. Alias rows are routes, not independent models.
"""
import csv
import json
import sys
from collections import Counter
from decimal import Decimal
from pathlib import Path

FIELDS = ('prompt', 'completion', 'input_cache_read')


def per_million(value):
    return None if value is None else str(Decimal(value) * 1_000_000)


def compare(payload):
    before = {row['id']: row for row in payload['before']['data']}
    after = {row['id']: row for row in payload['after']['data']}
    matched = sorted(before.keys() & after.keys())
    rows = []
    for route in matched:
        old, new = before[route], after[route]
        if old['pricing'] == new['pricing']:
            continue
        row = {'route': route, 'is_alias': bool(old.get('alias_target') or new.get('alias_target')),
               'old_alias_target': (old.get('alias_target') or {}).get('slug'),
               'new_alias_target': (new.get('alias_target') or {}).get('slug'),
               'changed_fields': sorted(k for k in old['pricing'].keys() | new['pricing'].keys()
                                        if old['pricing'].get(k) != new['pricing'].get(k)),
               'before_pricing': old['pricing'], 'after_pricing': new['pricing']}
        for field in FIELDS:
            row['before_' + field + '_usd_per_million'] = per_million(old['pricing'].get(field))
            row['after_' + field + '_usd_per_million'] = per_million(new['pricing'].get(field))
        rows.append(row)
    directions = Counter()
    for route in matched:
        a = before[route]['pricing'].get('prompt')
        b = after[route]['pricing'].get('prompt')
        if a is None or b is None or Decimal(a) < 0 or Decimal(b) < 0:
            directions['not_comparable'] += 1
        elif Decimal(a) == Decimal(b):
            directions['unchanged'] += 1
        else:
            directions['increased' if Decimal(b) > Decimal(a) else 'decreased'] += 1
    return {'matched_routes': len(matched), 'added_routes': sorted(after.keys() - before.keys()),
            'absent_routes': sorted(before.keys() - after.keys()), 'changed_pricing_records': len(rows),
            'changed_alias_records': sum(r['is_alias'] for r in rows),
            'unchanged_pricing_records': len(matched) - len(rows),
            'base_input_direction': dict(sorted(directions.items())), 'rows': rows}


if __name__ == '__main__':
    here = Path(__file__).resolve().parent
    source = Path(sys.argv[1]) if len(sys.argv) > 1 else here / 'paired-snapshots.json'
    out = Path(sys.argv[2]) if len(sys.argv) > 2 else here
    out.mkdir(parents=True, exist_ok=True)
    result = compare(json.loads(source.read_text()))
    (out / 'comparison.json').write_text(json.dumps(result, indent=2) + '\n')
    fields = ['route', 'is_alias', 'old_alias_target', 'new_alias_target', 'changed_fields'] + [
        side + '_' + f + '_usd_per_million' for f in FIELDS for side in ('before', 'after')]
    with (out / 'changed-prices.csv').open('w', newline='') as file:
        writer = csv.DictWriter(file, fieldnames=fields, extrasaction='ignore', lineterminator='\n')
        writer.writeheader()
        for row in result['rows']:
            writer.writerow({**row, 'changed_fields': '|'.join(row['changed_fields'])})
    print(json.dumps({k: v for k, v in result.items() if k != 'rows'}, indent=2))
