"""
Local SQLite storage for A2RAG decisions.
All data stays on customer's machine.
"""
from __future__ import annotations
import json, os, sqlite3, time
from pathlib import Path
from typing import List, Optional


DEFAULT_DB = Path.home() / ".a2rag" / "decisions.db"


class LocalStorage:
    def __init__(self, db_path: Optional[str] = None):
        self.db_path = Path(db_path or DEFAULT_DB)
        self.db_path.parent.mkdir(parents=True, exist_ok=True)
        self._init_db()

    def _conn(self):
        return sqlite3.connect(str(self.db_path))

    def _init_db(self):
        with self._conn() as conn:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS decisions (
                    id           TEXT PRIMARY KEY,
                    timestamp    REAL,
                    action       TEXT,
                    confidence   REAL,
                    query_type   TEXT,
                    language     TEXT,
                    latency_ms   REAL,
                    evidence     REAL,
                    completeness REAL,
                    ret_strength REAL,
                    missing_json TEXT,
                    reason_json  TEXT,
                    domain       TEXT,
                    metadata_json TEXT
                )
            """)
            conn.execute("""
                CREATE TABLE IF NOT EXISTS feedback (
                    decision_id  TEXT,
                    timestamp    REAL,
                    was_correct  INTEGER,
                    comment      TEXT
                )
            """)
            conn.execute("CREATE INDEX IF NOT EXISTS idx_ts ON decisions(timestamp)")
            conn.execute("CREATE INDEX IF NOT EXISTS idx_action ON decisions(action)")

    def save_decision(self, d) -> None:
        with self._conn() as conn:
            conn.execute("""
                INSERT OR REPLACE INTO decisions VALUES
                (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
            """, (
                d.decision_id, d.timestamp, d.action, d.confidence,
                d.query_type, d.language, d.latency_ms,
                d.signals.get("evidence", 0),
                d.signals.get("completeness", 1),
                d.signals.get("ret_strength", 0),
                json.dumps(d.missing_fields),
                json.dumps(d.reason_codes),
                d.metadata.get("domain") if d.metadata else None,
                json.dumps(d.metadata) if d.metadata else None,
            ))

    def save_feedback(self, decision_id: str, was_correct: bool, comment=None):
        with self._conn() as conn:
            conn.execute(
                "INSERT INTO feedback VALUES (?,?,?,?)",
                (decision_id, time.time(), int(was_correct), comment)
            )

    def query(self, days: int = 30, domain: Optional[str] = None) -> List[dict]:
        since = time.time() - (days * 86400)
        sql = "SELECT * FROM decisions WHERE timestamp > ?"
        params = [since]
        if domain:
            sql += " AND domain = ?"
            params.append(domain)
        with self._conn() as conn:
            conn.row_factory = sqlite3.Row
            rows = conn.execute(sql, params).fetchall()
        return [dict(r) for r in rows]

    def query_feedback(self, days: int = 30) -> List[dict]:
        since = time.time() - (days * 86400)
        with self._conn() as conn:
            conn.row_factory = sqlite3.Row
            rows = conn.execute(
                "SELECT f.*, d.action FROM feedback f "
                "LEFT JOIN decisions d ON f.decision_id = d.id "
                "WHERE f.timestamp > ?", [since]
            ).fetchall()
        return [dict(r) for r in rows]

    def export(self, path: str, days: int = 30, format: str = "csv") -> str:
        rows = self.query(days=days)
        if format == "csv":
            import csv
            with open(path, "w", newline="") as f:
                if rows:
                    writer = csv.DictWriter(f, fieldnames=rows[0].keys())
                    writer.writeheader()
                    writer.writerows(rows)
        elif format == "jsonl":
            with open(path, "w") as f:
                for r in rows:
                    f.write(json.dumps(r) + "\n")
        return path

    def clear(self, older_than_days: int = 90) -> int:
        cutoff = time.time() - (older_than_days * 86400)
        with self._conn() as conn:
            n = conn.execute(
                "DELETE FROM decisions WHERE timestamp < ?", [cutoff]
            ).rowcount
        return n
