"""
Persistance durable des fiches mission (au-delà du navigateur).

Stockage :
- une base SQLite (data/missions.db) : métadonnées + snapshot JSON complet du
  formulaire, pour pouvoir rouvrir/modifier/régénérer une fiche plus tard ;
- un dossier par fiche (data/mission_files/<id>/) pour les fichiers joints
  (images d'annexes, KML de chaque parcelle), réutilisés à la régénération si
  l'utilisateur ne les re-téléverse pas.

C'est plus durable que le brouillon navigateur : les fiches restent tant que le
poste/serveur conserve le dossier data/.
"""
import json
import os
import shutil
import sqlite3
import time

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# Répertoire de stockage. Par défaut ./data ; surchargé par la variable
# d'environnement FICHE_DATA_DIR (utile si le disque courant ne supporte pas
# le verrouillage SQLite, ex: certains montages réseau / bacs à sable).
DATA_DIR = os.environ.get("FICHE_DATA_DIR") or os.path.join(BASE_DIR, "data")
DB_PATH = os.path.join(DATA_DIR, "missions.db")
FILES_DIR = os.path.join(DATA_DIR, "mission_files")
os.makedirs(FILES_DIR, exist_ok=True)


def _connect():
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def init_db():
    with _connect() as conn:
        conn.execute(
            """
            CREATE TABLE IF NOT EXISTS missions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                ref_dossier TEXT,
                fiche_mission_n TEXT,
                type_mission TEXT,
                created_at REAL,
                updated_at REAL,
                data_json TEXT
            )
            """
        )


def mission_dir(mission_id):
    d = os.path.join(FILES_DIR, str(mission_id))
    os.makedirs(d, exist_ok=True)
    return d


def save_mission(data, mission_id=None):
    """Crée (mission_id=None) ou met à jour une fiche. `data` est le dict complet
    du formulaire (déjà nettoyé). Retourne l'id."""
    now = time.time()
    payload = json.dumps(data, ensure_ascii=False)
    with _connect() as conn:
        if mission_id:
            conn.execute(
                """UPDATE missions SET ref_dossier=?, fiche_mission_n=?, type_mission=?,
                   updated_at=?, data_json=? WHERE id=?""",
                (data.get("ref_dossier", ""), data.get("fiche_mission_n", ""),
                 data.get("type_mission", ""), now, payload, mission_id),
            )
            return mission_id
        cur = conn.execute(
            """INSERT INTO missions (ref_dossier, fiche_mission_n, type_mission,
               created_at, updated_at, data_json) VALUES (?,?,?,?,?,?)""",
            (data.get("ref_dossier", ""), data.get("fiche_mission_n", ""),
             data.get("type_mission", ""), now, now, payload),
        )
        return cur.lastrowid


def list_missions():
    with _connect() as conn:
        rows = conn.execute(
            "SELECT id, ref_dossier, fiche_mission_n, type_mission, updated_at "
            "FROM missions ORDER BY updated_at DESC"
        ).fetchall()
    return [dict(r) for r in rows]


def find_by_ref_num(ref_dossier, fiche_mission_n):
    """Retourne la fiche (métadonnées) ayant exactement cette réf. dossier et ce
    numéro de fiche, ou None. Sert au garde-fou anti-doublon."""
    ref = (ref_dossier or "").strip()
    num = (fiche_mission_n or "").strip()
    if not ref and not num:
        return None
    with _connect() as conn:
        row = conn.execute(
            "SELECT id, ref_dossier, fiche_mission_n, type_mission, updated_at "
            "FROM missions WHERE TRIM(ref_dossier)=? AND TRIM(fiche_mission_n)=? "
            "ORDER BY updated_at DESC LIMIT 1",
            (ref, num),
        ).fetchone()
    return dict(row) if row else None


def get_mission(mission_id):
    with _connect() as conn:
        row = conn.execute("SELECT * FROM missions WHERE id=?", (mission_id,)).fetchone()
    if not row:
        return None
    d = dict(row)
    d["data"] = json.loads(d.pop("data_json") or "{}")
    return d


def delete_mission(mission_id):
    with _connect() as conn:
        conn.execute("DELETE FROM missions WHERE id=?", (mission_id,))
    folder = os.path.join(FILES_DIR, str(mission_id))
    if os.path.isdir(folder):
        shutil.rmtree(folder, ignore_errors=True)


init_db()
