"""
Загрузка треков рейсов по аэропорту за дату.
Использование: python fetch_airport.py DME 2026-03-21
"""
import requests, json, time, os, sys
from datetime import datetime, timezone, timedelta
from dotenv import load_dotenv
from noise_model import calc_zone_radii_for_point

load_dotenv(dotenv_path='.env')
KEY = os.getenv('FLIGHTRADAR24_API_KEY')
BASE = 'https://fr24api.flightradar24.com/api'
HEADERS = {'Authorization': f'Bearer {KEY}', 'Accept': 'application/json', 'Accept-Version': 'v1'}

# ICAO коды аэропортов
AIRPORT_ICAO = {
    'SVO': 'UUEE',
    'DME': 'UUDD',
    'VKO': 'UUWW',
    'ZIA': 'UUBW',
}

BOUNDS_MO = '57.0,54.0,35.5,40.5'  # lat_max,lat_min,lon_min,lon_max
BBOX = {'lat_min': 54.0, 'lat_max': 57.0, 'lon_min': 35.5, 'lon_max': 40.5}

def in_mo(lat, lon):
    return BBOX['lat_min'] <= lat <= BBOX['lat_max'] and BBOX['lon_min'] <= lon <= BBOX['lon_max']

if len(sys.argv) < 3:
    print('Использование: python fetch_airport.py <AIRPORT> <DATE>')
    print('Пример: python fetch_airport.py DME 2026-03-21')
    sys.exit(1)

AIRPORT = sys.argv[1].upper()
DATE_STR = sys.argv[2]
ICAO = AIRPORT_ICAO.get(AIRPORT)
if not ICAO:
    print(f'Неизвестный аэропорт: {AIRPORT}. Доступны: {list(AIRPORT_ICAO.keys())}')
    sys.exit(1)

DATE = datetime.strptime(DATE_STR, '%Y-%m-%d').replace(tzinfo=timezone.utc)
RAW_FILE   = f'data/raw_{AIRPORT}_{DATE_STR}.json'
CACHE_DIR  = f'data/cache_{AIRPORT}'
OUT_FILE   = f'data/flights_{AIRPORT}_{DATE_STR}.json'
os.makedirs(CACHE_DIR, exist_ok=True)

# ── Шаг 1: снимки позиций (если нет кэша) ──────────────────────
if not os.path.exists(RAW_FILE):
    print(f'📡 Снимки за {DATE_STR} ({AIRPORT}/{ICAO}), интервал 3ч...')
    all_flights = {}
    for hour in range(0, 24, 3):
        ts = int((DATE + timedelta(hours=hour)).timestamp())
        r = requests.get(f'{BASE}/historic/flight-positions/full', headers=HEADERS,
            params={'bounds': BOUNDS_MO, 'timestamp': ts, 'limit': 500}, timeout=20)
        if not r.ok:
            print(f'  ❌ {hour:02d}:00 → {r.status_code}')
            continue
        data = r.json().get('data', [])
        ap_flights = [f for f in data if f.get('orig_icao') == ICAO or f.get('dest_icao') == ICAO]
        print(f'  ✅ {hour:02d}:00 → всего: {len(data)}, {AIRPORT}: {len(ap_flights)}')
        for item in ap_flights:
            fid = item.get('fr24_id', '')
            if not fid: continue
            if fid not in all_flights:
                all_flights[fid] = {
                    'id': fid, 'callsign': item.get('callsign',''),
                    'flight_number': item.get('flight',''),
                    'aircraft_type': item.get('type',''),
                    'registration':  item.get('reg',''),
                    'orig_icao':     item.get('orig_icao',''),
                    'dest_icao':     item.get('dest_icao',''),
                    'origin':        item.get('orig_iata',''),
                    'destination':   item.get('dest_iata',''),
                    'points': []
                }
            all_flights[fid]['points'].append({
                'lat': item.get('lat',0), 'lon': item.get('lon',0),
                'alt': item.get('alt',0), 'gspeed': item.get('gspeed',0),
                'track': item.get('track',0), 'timestamp': item.get('timestamp',''),
            })
        time.sleep(1)
    with open(RAW_FILE, 'w') as f:
        json.dump({'date': DATE_STR, 'airport': AIRPORT, 'flights': list(all_flights.values())}, f)
    print(f'  → {len(all_flights)} уникальных {AIRPORT} рейсов\n')
else:
    print(f'📂 Снимки из кэша: {RAW_FILE}')

# ── Шаг 2: треки ────────────────────────────────────────────────
with open(RAW_FILE) as f:
    raw = json.load(f)

flights_raw = raw['flights']
print(f'📡 Загружаем треки для {len(flights_raw)} рейсов...')

flights_final = []
errors = 0

for i, flight in enumerate(flights_raw):
    fid = flight['id']
    cache = f'{CACHE_DIR}/track_{fid}.json'
    if os.path.exists(cache):
        with open(cache) as f:
            tracks = json.load(f)
    else:
        r = requests.get(f'{BASE}/flight-tracks', headers=HEADERS,
            params={'flight_id': fid}, timeout=20)
        if r.status_code == 429:
            print(f'  ⏳ 429 на {i}, пауза 30с...')
            time.sleep(30)
            r = requests.get(f'{BASE}/flight-tracks', headers=HEADERS,
                params={'flight_id': fid}, timeout=20)
        if not r.ok:
            errors += 1
            continue
        raw_r = r.json()
        tracks = raw_r[0].get('tracks', []) if isinstance(raw_r, list) and raw_r else []
        with open(cache, 'w') as f:
            json.dump(tracks, f)
        time.sleep(1.2)

    mo_pts = sorted([p for p in tracks if in_mo(p.get('lat',0), p.get('lon',0))],
                    key=lambda p: p.get('timestamp',''))
    if len(mo_pts) < 2:
        continue

    points = []
    for pt in mo_pts:
        alt_ft = pt.get('alt', 0) or 0
        alt_m  = round(alt_ft / 3.28084)
        points.append({
            'lat': pt['lat'], 'lon': pt['lon'],
            'altitude': alt_ft, 'altitude_m': alt_m,
            'speed': pt.get('gspeed', 0), 'heading': pt.get('track', 0),
            'timestamp': pt.get('timestamp', ''),
            'zone_radii': calc_zone_radii_for_point(alt_m),
        })

    flights_final.append({
        'id': fid, 'callsign': flight['callsign'],
        'flight_number': flight['flight_number'],
        'aircraft_type': flight['aircraft_type'],
        'registration':  flight['registration'],
        'airline':       flight['callsign'][:3],
        'origin':        flight['origin'],
        'destination':   flight['destination'],
        'orig_icao':     flight['orig_icao'],
        'dest_icao':     flight['dest_icao'],
        'airport':       AIRPORT,
        'type': 'departure' if flight['orig_icao'] == ICAO else 'arrival',
        'points': points,
    })

    if (i+1) % 5 == 0:
        print(f'  {i+1}/{len(flights_raw)}: {len(flights_final)} рейсов с треками')

print(f'\n✅ {AIRPORT}: {len(flights_final)} рейсов, ошибок: {errors}')

with open(OUT_FILE, 'w', encoding='utf-8') as f:
    json.dump({'airport': AIRPORT, 'date': DATE_STR,
               'flights_count': len(flights_final), 'flights': flights_final}, f, ensure_ascii=False)

total_pts = sum(len(f['points']) for f in flights_final)
print(f'📍 Точек над МО: {total_pts}')
print(f'💾 {OUT_FILE}')
for flt in flights_final[:5]:
    pts = flt['points']
    d = '🛫' if flt['type'] == 'departure' else '🛬'
    print(f"  {d} {flt['flight_number']:8} {flt['aircraft_type']:5} "
          f"{flt['origin']:3}→{flt['destination']:3} | {len(pts)} точек")
