"""SQLite persistence for waypoints and routes."""
import sqlite3, json, uuid
from pathlib import Path
from datetime import datetime, timezone


def _conn(db_path: Path):
    con = sqlite3.connect(db_path)
    con.row_factory = sqlite3.Row
    return con


def init_db(db_path: Path):
    db_path.parent.mkdir(parents=True, exist_ok=True)
    con = _conn(db_path)
    con.executescript("""
        CREATE TABLE IF NOT EXISTS waypoints (
            id         TEXT PRIMARY KEY,
            name       TEXT NOT NULL,
            lat        REAL NOT NULL,
            lon        REAL NOT NULL,
            notes      TEXT,
            mark_type  TEXT DEFAULT '',
            locked     INTEGER DEFAULT 0,
            created_at TEXT
        );
        CREATE TABLE IF NOT EXISTS routes (
            id          TEXT PRIMARY KEY,
            name        TEXT NOT NULL,
            wpt_ids     TEXT NOT NULL,   -- JSON array of waypoint ids in order
            created_at  TEXT
        );
        CREATE TABLE IF NOT EXISTS track_log (
            id         INTEGER PRIMARY KEY AUTOINCREMENT,
            lat        REAL,
            lon        REAL,
            sog        REAL,
            cog        REAL,
            alt        REAL,
            hdop       REAL,
            ts         TEXT
        );
    """)
    con.commit()
    # Migration: add mark_type column to existing DBs that don't have it
    try:
        con.execute("ALTER TABLE waypoints ADD COLUMN mark_type TEXT DEFAULT ''")
        con.commit()
    except Exception:
        pass   # column already exists
    try:
        con.execute("ALTER TABLE waypoints ADD COLUMN locked INTEGER DEFAULT 0")
        con.commit()
    except Exception:
        pass
    con.close()


# ── Waypoints ─────────────────────────────────────────────────────────────────

def get_waypoints(db_path: Path) -> list:
    con = _conn(db_path)
    rows = con.execute("SELECT * FROM waypoints ORDER BY created_at").fetchall()
    con.close()
    return [dict(r) for r in rows]


def save_waypoint(db_path: Path, data: dict) -> dict:
    wid = data.get("id") or str(uuid.uuid4())[:8].upper()
    now = datetime.now(timezone.utc).isoformat()
    con = _conn(db_path)
    con.execute("""
        INSERT INTO waypoints (id, name, lat, lon, notes, mark_type, locked, created_at)
        VALUES (?,?,?,?,?,?,?,?)
        ON CONFLICT(id) DO UPDATE SET
            name=excluded.name, lat=excluded.lat, lon=excluded.lon,
            notes=excluded.notes, mark_type=excluded.mark_type,
            locked=excluded.locked
    """, (wid, data["name"], data["lat"], data["lon"],
          data.get("notes", ""), data.get("mark_type", ""),
          int(data.get("locked", 0)),
          data.get("created_at", now)))
    con.commit()
    con.close()
    return {**data, "id": wid, "created_at": now}


def delete_waypoint(db_path: Path, wid: str):
    con = _conn(db_path)
    con.execute("DELETE FROM waypoints WHERE id=?", (wid,))
    con.commit()
    con.close()


# ── Routes ────────────────────────────────────────────────────────────────────

def get_routes(db_path: Path) -> list:
    con = _conn(db_path)
    rows = con.execute("SELECT * FROM routes ORDER BY created_at").fetchall()
    con.close()
    result = []
    for r in rows:
        d = dict(r)
        d["wpt_ids"] = json.loads(d["wpt_ids"])
        result.append(d)
    return result


def save_route(db_path: Path, data: dict) -> dict:
    rid = data.get("id") or str(uuid.uuid4())[:8].upper()
    now = datetime.now(timezone.utc).isoformat()
    con = _conn(db_path)
    con.execute("""
        INSERT INTO routes (id, name, wpt_ids, created_at)
        VALUES (?,?,?,?)
        ON CONFLICT(id) DO UPDATE SET
            name=excluded.name, wpt_ids=excluded.wpt_ids
    """, (rid, data["name"], json.dumps(data.get("wpt_ids", [])),
          data.get("created_at", now)))
    con.commit()
    con.close()
    return {**data, "id": rid, "wpt_ids": data.get("wpt_ids", []), "created_at": now}


def delete_route(db_path: Path, rid: str):
    con = _conn(db_path)
    con.execute("DELETE FROM routes WHERE id=?", (rid,))
    con.commit()
    con.close()


# ── Track log ─────────────────────────────────────────────────────────────────

def log_position(db_path: Path, fix: dict):
    con = _conn(db_path)
    con.execute(
        "INSERT INTO track_log (lat,lon,sog,cog,alt,hdop,ts) VALUES (?,?,?,?,?,?,?)",
        (fix.get("lat"), fix.get("lon"), fix.get("sog"), fix.get("cog"),
         fix.get("altitude"), fix.get("hdop"),
         datetime.now(timezone.utc).isoformat())
    )
    con.commit()
    con.close()


def get_track(db_path: Path, limit: int = 2000) -> list:
    con = _conn(db_path)
    rows = con.execute(
        "SELECT lat,lon,sog,cog,alt,hdop,ts FROM track_log ORDER BY id DESC LIMIT ?",
        (limit,)
    ).fetchall()
    con.close()
    return [dict(r) for r in reversed(rows)]


def clear_track(db_path: Path):
    con = _conn(db_path)
    con.execute("DELETE FROM track_log")
    con.commit()
    con.close()
