"""
Database management for .yoromaps files.

A .yoromaps file is a single SQLite database containing:
- tiles: MBTiles-compatible tile storage
- nodes: road graph intersections
- edges: road graph segments
- pois: points of interest
- metadata: version, country, timestamps
"""

from __future__ import annotations

import sqlite3
from pathlib import Path

SCHEMA_VERSION = 1

SCHEMA_SQL = """
-- Metadata
CREATE TABLE IF NOT EXISTS metadata (
    key   TEXT PRIMARY KEY,
    value TEXT
);

-- MBTiles-compatible tile storage
CREATE TABLE IF NOT EXISTS tiles (
    zoom_level  INTEGER NOT NULL,
    tile_column INTEGER NOT NULL,
    tile_row    INTEGER NOT NULL,
    tile_data   BLOB NOT NULL,
    PRIMARY KEY (zoom_level, tile_column, tile_row)
);

-- Road graph: nodes (intersections)
CREATE TABLE IF NOT EXISTS nodes (
    id  INTEGER PRIMARY KEY,
    lat REAL NOT NULL,
    lon REAL NOT NULL
);

-- Road graph: edges (road segments)
CREATE TABLE IF NOT EXISTS edges (
    id        INTEGER PRIMARY KEY AUTOINCREMENT,
    from_node INTEGER NOT NULL REFERENCES nodes(id),
    to_node   INTEGER NOT NULL REFERENCES nodes(id),
    distance_m REAL NOT NULL,
    duration_s REAL NOT NULL,
    road_type  TEXT NOT NULL DEFAULT 'road',
    oneway     INTEGER NOT NULL DEFAULT 0,
    name       TEXT DEFAULT ''
);
CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_node);
CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_node);

-- Points of interest
CREATE TABLE IF NOT EXISTS pois (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    lat        REAL NOT NULL,
    lon        REAL NOT NULL,
    yoro_code  TEXT NOT NULL DEFAULT '',
    name       TEXT NOT NULL,
    category   TEXT NOT NULL DEFAULT 'other',
    source     TEXT NOT NULL DEFAULT 'local',
    osm_id     INTEGER,
    created_at TEXT NOT NULL DEFAULT (datetime('now')),
    updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_pois_yoro ON pois(yoro_code);
CREATE INDEX IF NOT EXISTS idx_pois_category ON pois(category);
"""


def open_db(path: str | Path, create: bool = False) -> sqlite3.Connection:
    """Open a .yoromaps database. Creates schema if *create* is True."""
    path = Path(path)
    exists = path.exists()

    if not exists and not create:
        raise FileNotFoundError(f"Database not found: {path}")

    conn = sqlite3.connect(str(path))
    conn.row_factory = sqlite3.Row
    conn.execute("PRAGMA journal_mode=WAL")
    conn.execute("PRAGMA synchronous=NORMAL")
    conn.execute("PRAGMA foreign_keys=ON")

    if create and not exists:
        conn.executescript(SCHEMA_SQL)
        conn.execute("INSERT OR REPLACE INTO metadata VALUES ('schema_version', ?)",
                      (str(SCHEMA_VERSION),))
        conn.commit()

    return conn


def set_metadata(conn: sqlite3.Connection, key: str, value: str) -> None:
    conn.execute("INSERT OR REPLACE INTO metadata VALUES (?, ?)", (key, value))
    conn.commit()


def get_metadata(conn: sqlite3.Connection, key: str) -> str | None:
    row = conn.execute("SELECT value FROM metadata WHERE key = ?", (key,)).fetchone()
    return row[0] if row else None


def db_config(path: str) -> dict:
    """Return a Django DATABASES dict entry for a .yoromaps file."""
    return {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": str(path),
    }
