"""
FlightAware tracks service.
- GET  /health               — healthcheck
- POST /run?date=YYYY-MM-DD  — manual trigger
"""
import logging
import sys
import time
from datetime import date, timedelta, datetime, timezone

import psycopg2
import psycopg2.extras
from flask import Flask, jsonify, request

from config import config
from fa_worker import run as worker_run

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [tracks-fa] %(levelname)s %(message)s",
    datefmt="%Y-%m-%dT%H:%M:%S",
    handlers=[logging.StreamHandler(sys.stdout)],
)
log = logging.getLogger("tracks_fa")

app = Flask(__name__)

_last_run: dict = {"at": None, "status": "never", "stats": {}}
_conn = None


def get_conn():
    global _conn
    if _conn is None or _conn.closed:
        _conn = psycopg2.connect(config.DB_DSN)
        psycopg2.extras.register_uuid(_conn)
        log.info("DB connection established")
    return _conn


def wait_for_db(max_attempts: int = 30):
    for attempt in range(1, max_attempts + 1):
        try:
            get_conn()
            return
        except psycopg2.OperationalError as e:
            log.warning("DB not ready (%d/%d): %s", attempt, max_attempts, e)
            time.sleep(3)
    raise SystemExit("Could not connect to DB")


@app.get("/health")
def health():
    try:
        get_conn().cursor().execute("SELECT 1")
        db_ok = True
    except Exception:
        db_ok = False
    return jsonify({
        "status": "ok" if db_ok else "degraded",
        "db": "ok" if db_ok else "error",
        "last_run": _last_run,
    }), 200 if db_ok else 503


@app.post("/run")
def run_manual():
    date_str = request.args.get("date")
    if date_str:
        try:
            target = date.fromisoformat(date_str)
        except ValueError:
            return jsonify({"error": "invalid date, use YYYY-MM-DD"}), 400
    else:
        target = date.today() - timedelta(days=1)

    if _last_run.get("status") == "running":
        return jsonify({"error": "already running"}), 409

    _last_run["at"] = datetime.now(timezone.utc).isoformat()
    _last_run["status"] = "running"

    try:
        conn = get_conn()
        stats = worker_run(target, conn)
        _last_run.update(status="ok", stats=stats)
        return jsonify({"status": "ok", "stats": stats})
    except Exception as e:
        _last_run["status"] = f"error: {e}"
        log.error("run failed: %s", e)
        return jsonify({"error": str(e)}), 500


if __name__ == "__main__":
    wait_for_db()
    open("/tmp/ready", "w").close()
    log.info("Starting FA tracks service on port 8002")
    app.run(host="0.0.0.0", port=8002, debug=False)
