#!/usr/bin/env python3
from __future__ import annotations

import json
import shutil
from pathlib import Path
from typing import Iterable

import joblib

REPO_ROOT = Path(__file__).resolve().parents[1]
BASELINE_DIR = REPO_ROOT / 'artifacts' / 'v4_models_frozen_2026-03-20'
SERVING_DIR = REPO_ROOT / 'artifacts' / 'v4_models_serving_current'
SUMMARY_PATHS = [
    REPO_ROOT / 'experiments' / 'priority_opt_pass1' / 'summary.json',
    REPO_ROOT / 'experiments' / 'low75_opt_pass1' / 'summary.json',
]
IMPROVED_DIRS = {
    REPO_ROOT / 'experiments' / 'priority_opt_pass1' / 'summary.json': REPO_ROOT / 'experiments' / 'priority_opt_pass1' / 'improved_models',
    REPO_ROOT / 'experiments' / 'low75_opt_pass1' / 'summary.json': REPO_ROOT / 'experiments' / 'low75_opt_pass1' / 'improved_models',
}


def iter_summary_rows(paths: Iterable[Path]) -> list[tuple[Path, dict]]:
    rows: list[tuple[Path, dict]] = []
    for path in paths:
        data = json.loads(path.read_text(encoding='utf-8'))
        for row in data:
            rows.append((path, row))
    return rows


def deploy() -> list[dict]:
    SERVING_DIR.mkdir(parents=True, exist_ok=True)
    for file in SERVING_DIR.glob('*'):
        if file.is_file():
            file.unlink()

    for file in BASELINE_DIR.glob('*_pro_v4_*.pkl'):
        shutil.copy2(file, SERVING_DIR / file.name)

    deployed = []
    for summary_path, row in iter_summary_rows(SUMMARY_PATHS):
        code = row['code']
        if row.get('improved'):
            improved_dir = IMPROVED_DIRS[summary_path]
            for suffix in ['config', 'model', 'scaler']:
                src = improved_dir / f'{code}_pro_v4_{suffix}.pkl'
                if not src.exists():
                    raise FileNotFoundError(f'missing improved artifact: {src}')
                shutil.copy2(src, SERVING_DIR / src.name)

        cfg = joblib.load(SERVING_DIR / f'{code}_pro_v4_config.pkl')
        deployed.append({
            'code': code,
            'league': cfg.get('league', row.get('league', code)),
            'model_name': cfg.get('model_name'),
            'bet_acc': float(cfg.get('bet_acc', 0.0)),
            'threshold': float(cfg.get('threshold', 0.55)),
            'feature_mode': cfg.get('feature_mode', 'baseline_v4'),
            'feature_count': len(cfg.get('features', [])),
            'source': 'improved' if row.get('improved') else 'baseline',
        })

    deployed.sort(key=lambda x: x['code'])
    (SERVING_DIR / 'manifest.json').write_text(
        json.dumps(deployed, ensure_ascii=False, indent=2),
        encoding='utf-8',
    )
    return deployed


if __name__ == '__main__':
    manifest = deploy()
    print(json.dumps({
        'serving_dir': str(SERVING_DIR),
        'count': len(manifest),
        'improved_count': sum(1 for row in manifest if row['source'] == 'improved'),
        'baseline_count': sum(1 for row in manifest if row['source'] == 'baseline'),
    }, ensure_ascii=False, indent=2))
