"""Apply the 2026/27 season team_map corrections. Dry run unless --apply.

Three distinct problems, fixed separately because they fail differently:

  RENAMES   football-data.co.uk changed a club's spelling. The club never moved,
            but the `fdco` field no longer matches the results CSV, so bet
            resolution via that fallback silently stops finding the fixture.

  STALE DIV The club was promoted or relegated. `div` still names last season's
            division, so league gating and season lookups use the wrong one.

  MISSING   No entry at all. kalshi_live falls through and 404s, which shows up
            only as a permanent Kalshi=?A/?H (memory/feedback_team_map_silent_miss).

Every Kalshi abbreviation below was HARVESTED from real event tickers by
research/harvest_kalshi_abbrs.py -- none is guessed. The 2026-05-19 audit found
three wrong guesses in the map, so this rule is not optional.

Usage:  python research\\fix_team_map_2627.py [--apply]
"""
import json
import shutil
import sys
from datetime import datetime
from pathlib import Path

MAP = Path(r'E:\soccer\data\team_map.json')

# fdco spelling changed; club did NOT move. Keyed by the OLD fdco value.
RENAME_FDCO = {
    'Ath Madrid': 'Atl. Madrid',
    'Vallecano': 'Rayo Vallecano',
    'La Coruna': 'Dep. A Coruna',
    'Bradford': 'Bradford City',
}

# API-Football name -> division it is in for 2026/27
SET_DIV = {
    'FC Heidenheim': 'D2', 'St. Pauli': 'D2', 'VfL Wolfsburg': 'D2',
    'Bolton': 'E1', 'Burnley': 'E1', 'Cardiff': 'E1', 'Lincoln': 'E1',
    'West Ham United': 'E1', 'Wolverhampton Wanderers': 'E1',
    'Leicester': 'E2', 'Oxford United': 'E2', 'Sheffield Wednesday': 'E2',
    'Bradford': 'E2',
    'Malaga': 'SP1', 'Santander': 'SP1',
    'Girona': 'SP2', 'Mallorca': 'SP2', 'Oviedo': 'SP2',
    # Second pass: these three were hidden behind the "no kalshi abbr" and
    # "fdco renamed" buckets on the first run, so their stale div only became
    # visible once those were fixed.
    'Bromley': 'E2', 'Notts County': 'E2',
    'Deportivo de La Coruna': 'SP1',
}

# Mapped already, but carrying no Kalshi abbreviation.
SET_ABBR = {
    'Bromley': 'BRO',
    'Notts County': 'NOC',
    'Bradford': 'BRA',
}

# Brand new entries: (AF name, div, fdco, kalshi abbr, aliases)
# kalshi='' means Kalshi does not currently list the club -- the entry still
# earns its place because the fdco half makes bet resolution work.
NEW = [
    ('SK Beveren',        'B1',  'Beveren',            'BEV', []),
    ('Lommel United',     'B1',  'Lommel SK',          'LOM', []),
    ('Energie Cottbus',   'D2',  'Cottbus',            'COT', []),
    ('VfL Osnabruck',     'D2',  'Osnabruck',          'OSN', ['VfL Osnabr\u00fcck']),
    ('Cambuur',           'N1',  'Cambuur',            'CAM', []),
    ('ADO Den Haag',      'N1',  'Den Haag',           'ADO', []),
    ('Willem II',         'N1',  'Willem II',          '',    []),
    ('Academico Viseu',   'P1',  'Academico Viseu',    'ACV', []),
    ('Maritimo',          'P1',  'Maritimo',           'CSM', []),
    ('ST Johnstone',      'SC0', 'St Johnstone',       'JOH', ['St Johnstone',
                                                               'St. Johnstone']),
    ('Amed',              'T1',  'Amedspor',           'AMS', ['Amedspor']),
    ('\u00c7orum FK',     'T1',  'Corum',              'COR', ['Corum FK', 'Corum']),
    ('Erzurumspor FK',    'T1',  'Erzurumspor',        'ERZ', []),
    ('Celta de Vigo II',  'SP2', 'Celta B',            'RCC', []),
    ('Eldense',           'SP2', 'Eldense',            'CDE', []),
    ('Sabadell',          'SP2', 'Sabadell',           'SAB', []),
    ('Tenerife',          'SP2', 'Tenerife',           'TEN', []),
    ('Cambridge United',  'E2',  'Cambridge',          'CAM', []),
    ('Milton Keynes Dons', 'E2', 'Milton Keynes Dons', 'MKD', []),
]


def main():
    apply = '--apply' in sys.argv
    m = json.loads(MAP.read_text(encoding='utf-8'))
    changes = []

    by_fdco = {}
    for k, v in m.items():
        if isinstance(v, dict) and v.get('fdco'):
            by_fdco.setdefault(v['fdco'], []).append(k)

    for old, new in RENAME_FDCO.items():
        keys = by_fdco.get(old) or []
        if not keys:
            changes.append(('SKIP', f'rename {old!r}: no entry with that fdco'))
            continue
        for k in keys:
            changes.append(('RENAME', f'{k}: fdco {old!r} -> {new!r}'))
            if apply:
                m[k]['fdco'] = new

    for af, div in SET_DIV.items():
        if af not in m or not isinstance(m[af], dict):
            changes.append(('SKIP', f'div {af!r}: not in map'))
            continue
        cur = m[af].get('div')
        if cur == div:
            continue
        changes.append(('DIV', f'{af}: {cur!r} -> {div!r}'))
        if apply:
            m[af]['div'] = div

    for af, ab in SET_ABBR.items():
        if af not in m or not isinstance(m[af], dict):
            changes.append(('SKIP', f'abbr {af!r}: not in map'))
            continue
        cur = m[af].get('kalshi') or ''
        if cur == ab:
            continue
        changes.append(('ABBR', f'{af}: kalshi {cur!r} -> {ab!r}'))
        if apply:
            m[af]['kalshi'] = ab

    for af, div, fdco, ab, aliases in NEW:
        if af in m:
            changes.append(('SKIP', f'new {af!r}: already present'))
            continue
        entry = {'div': div, 'fdco': fdco, 'kalshi': ab}
        if aliases:
            entry['aliases'] = aliases
        changes.append(('NEW', f'{af}: {json.dumps(entry, ensure_ascii=False)}'))
        if apply:
            m[af] = entry

    for kind, msg in changes:
        print(f'  {kind:7} {msg}')
    counts = {}
    for kind, _ in changes:
        counts[kind] = counts.get(kind, 0) + 1
    print()
    print('summary:', ', '.join(f'{k}={v}' for k, v in sorted(counts.items())))
    print(f'entries before: {len(json.loads(MAP.read_text(encoding="utf-8")))}, after: {len(m)}')

    if not apply:
        print('\nDRY RUN -- nothing written. Re-run with --apply.')
        return

    stamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    bak = MAP.with_suffix(f'.json.bak_{stamp}')
    shutil.copy2(MAP, bak)
    tmp = MAP.with_suffix('.json.tmp')
    tmp.write_text(json.dumps(m, indent=2, ensure_ascii=False, sort_keys=True),
                   encoding='utf-8')
    # validate before swapping in
    json.loads(tmp.read_text(encoding='utf-8'))
    tmp.replace(MAP)
    print(f'\nbacked up to {bak.name}')
    print(f'wrote {MAP}')


if __name__ == '__main__':
    main()
