"""Dry-run by default. --allow-paid explicitly permits real API calls."""
import argparse
import json
import statistics
import time
from datetime import datetime, timezone
from pathlib import Path

from chat import request, RequestError

PROMPTS = [
    ('russian', 'Объясни школьнику, что такое API, в двух предложениях.'),
    ('code', 'Напиши функцию Python, возвращающую уникальные элементы списка с сохранением порядка.'),
    ('structure', 'Верни JSON с полями name и city: Анна живёт в Казани. Без дополнительного текста.'),
]


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--model', action='append', default=None)
    parser.add_argument('--runs', type=int, choices=range(1, 4), default=1)
    parser.add_argument('--allow-paid', action='store_true')
    parser.add_argument('--output', default='.local/benchmarks/results.jsonl')
    args = parser.parse_args()
    models = args.model or ['gpt-mini']
    if len(models) > 4:
        parser.error('At most four models per run.')
    plan = {'models': models, 'cases': len(PROMPTS), 'runs': args.runs,
            'requests': len(models) * len(PROMPTS) * args.runs, 'max_tokens': 512,
            'temperature': 0.2, 'measurement': 'full non-streaming response',
            'paid_execution': args.allow_paid, 'automatic_retries': False}
    print(json.dumps(plan, ensure_ascii=False))
    if not args.allow_paid:
        print('Plan only. No API calls made. --allow-paid permits requests that may incur charges.')
        return
    output = Path(args.output)
    output.parent.mkdir(parents=True, exist_ok=True)
    rows = []
    for model in models:
        for case, prompt in PROMPTS:
            for run in range(args.runs):
                row = {'model': model, 'case': case, 'run': run + 1,
                       'date': datetime.now(timezone.utc).isoformat()}
                start = time.perf_counter()
                try:
                    payload = request(model, prompt)
                    content = payload['choices'][0]['message']['content']
                    if not isinstance(content, str) or not content:
                        raise RequestError('Empty or invalid response')
                    usage = payload.get('usage') or {}
                    row.update(status='success', prompt_tokens=usage.get('prompt_tokens'),
                               completion_tokens=usage.get('completion_tokens'),
                               cost_rub=usage.get('cost_rub'))
                except (RequestError, KeyError, IndexError, TypeError):
                    row.update(status='error', cost_rub=None, reconciliation_required=True)
                row['elapsed_ms'] = round((time.perf_counter() - start) * 1000, 2)
                # No keys, prompts, provider messages or model answers in the report.
                with output.open('a', encoding='utf-8') as stream:
                    stream.write(json.dumps(row, ensure_ascii=False) + '\n')
                rows.append(row)
    for model in models:
        subset = [r for r in rows if r['model'] == model]
        success = [r for r in subset if r['status'] == 'success']
        timings = [r['elapsed_ms'] for r in success]
        print(json.dumps({'model': model, 'successes': len(success), 'errors': len(subset)-len(success),
                          'median_ms': statistics.median(timings) if timings else None,
                          'minimum_ms': min(timings) if timings else None,
                          'maximum_ms': max(timings) if timings else None}))
    print('Local results:', output)
    print('Review responses separately for quality. Reconcile failed requests before repeating.')


if __name__ == '__main__':
    main()
