import os
import psycopg2

COUNTRY_FALLBACK = {
    "FR": "France",
    "DE": "Germany",
    "IT": "Italy",
    "GB": "United Kingdom",
    "ES": "Spain",
    "SE": "Sweden",
    "NO": "Norway",
    "FI": "Finland",
    "PL": "Poland",
    "NL": "Netherlands",
    "BE": "Belgium",
    "CH": "Switzerland",
    "AT": "Austria",
    "PT": "Portugal",
    "GR": "Greece",
    "CZ": "Czech Republic",
    "SK": "Slovakia",
    "SI": "Slovenia",
    "HU": "Hungary",
    "UA": "Ukraine",
    "RU": "Russia",
    "DK": "Denmark",
}

def make_query(location_text: str, country_code: str) -> str:
    loc = (location_text or "").strip()
    cc = (country_code or "").strip().upper()
    ctry = COUNTRY_FALLBACK.get(cc, cc)
    return f"{loc}, {ctry}" if loc else ctry

def main():
    dsn = os.environ["DATABASE_URL"]
    batch = int(os.environ.get("GEOCODE_ENQUEUE_BATCH", "5000"))

    # Retry policy
    retry_after_hours = int(os.environ.get("GEOCODE_RETRY_AFTER_HOURS", "72"))  # 72h = 3 jours
    force_retry = os.environ.get("GEOCODE_FORCE_RETRY", "0").strip() in ("1", "true", "yes", "on")

    conn = psycopg2.connect(dsn)
    conn.autocommit = True

    with conn.cursor() as cur:
        # On sélectionne :
        # - bands non géocodés avec location_text
        # - soit pas encore en queue, soit queue en error/queued et next_run_at <= now()
        # - et si erreur récente: on respecte retry_after_hours sauf si force_retry
        cur.execute(
            """
            SELECT
              b.ma_id, b.country, b.location_text
            FROM bands b
            LEFT JOIN geocode_queue q ON q.ma_id = b.ma_id
            WHERE b.geom IS NULL
              AND b.location_text IS NOT NULL AND b.location_text <> ''
              AND (
                   q.ma_id IS NULL
                   OR (q.status IN ('queued','error') AND q.next_run_at <= now())
              )
              AND (
                   %s
                   OR b.geocode_error IS NULL
                   OR b.geocode_error_at IS NULL
                   OR b.geocode_error_at < now() - (%s || ' hours')::interval
              )
            ORDER BY
              COALESCE(q.next_run_at, now()) ASC,
              b.ma_id ASC
            LIMIT %s
            """,
            (force_retry, retry_after_hours, batch),
        )

        rows = cur.fetchall()
        enq = 0

        for ma_id, country, location_text in rows:
            qtxt = make_query(location_text, country)

            cur.execute(
                """
                INSERT INTO geocode_queue (ma_id, query, country, status, next_run_at)
                VALUES (%s, %s, %s, 'queued', now())
                ON CONFLICT (ma_id) DO UPDATE
                  SET query = EXCLUDED.query,
                      country = EXCLUDED.country,
                      status = CASE
                        WHEN geocode_queue.status IN ('done','processing') THEN geocode_queue.status
                        ELSE 'queued'
                      END,
                      next_run_at = CASE
                        WHEN geocode_queue.status IN ('done','processing') THEN geocode_queue.next_run_at
                        ELSE now()
                      END,
                      updated_at = now()
                """,
                (ma_id, qtxt, country),
            )
            enq += 1

        print(f"[enqueue] queued_or_updated={enq} (selected={len(rows)}) force_retry={force_retry} retry_after_hours={retry_after_hours}")

    conn.close()

if __name__ == "__main__":
    main()
