"""SQLite database connection and schema management."""

from __future__ import annotations

import sqlite3
from contextlib import contextmanager
from typing import Generator

from .config import settings

_SCHEMA = """\
CREATE TABLE IF NOT EXISTS api_keys (
    id         TEXT PRIMARY KEY,
    key_hash   TEXT NOT NULL UNIQUE,
    org_name   TEXT NOT NULL,
    created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
    is_active  INTEGER NOT NULL DEFAULT 1
);

CREATE TABLE IF NOT EXISTS receipts (
    id            INTEGER PRIMARY KEY AUTOINCREMENT,
    api_key_id    TEXT NOT NULL REFERENCES api_keys(id),
    idx           INTEGER NOT NULL,
    timestamp     TEXT NOT NULL,
    agent_id      TEXT,
    tool_name     TEXT NOT NULL,
    query_hash    TEXT NOT NULL,
    response_hash TEXT NOT NULL,
    record_hash   TEXT NOT NULL,
    root_hash     TEXT NOT NULL,
    proof_path    TEXT NOT NULL,
    proof_root    TEXT NOT NULL,
    received_at   TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
    UNIQUE(api_key_id, idx)
);

CREATE TABLE IF NOT EXISTS anchors (
    id            INTEGER PRIMARY KEY AUTOINCREMENT,
    api_key_id    TEXT NOT NULL REFERENCES api_keys(id),
    root_hash     TEXT NOT NULL,
    receipt_count INTEGER NOT NULL,
    created_at    TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
    UNIQUE(api_key_id, root_hash)
);
"""


def get_connection(db_path: str | None = None) -> sqlite3.Connection:
    """Create a new SQLite connection with WAL mode and foreign keys."""
    path = db_path or settings.db_path
    conn = sqlite3.connect(path)
    conn.row_factory = sqlite3.Row
    conn.execute("PRAGMA journal_mode=WAL")
    conn.execute("PRAGMA foreign_keys=ON")
    return conn


def init_db(conn: sqlite3.Connection) -> None:
    """Create tables if they don't exist."""
    conn.executescript(_SCHEMA)


def get_db() -> Generator[sqlite3.Connection, None, None]:
    """FastAPI dependency that yields a connection per request."""
    conn = get_connection()
    try:
        yield conn
        conn.commit()
    finally:
        conn.close()
