"""
neurocli session — SQLite-backed session history + coding stats
"""
import sqlite3
import json
import time
from datetime import datetime
from pathlib import Path
from .config import SESSIONS_DB, STATS_FILE, ensure_dirs


def get_db():
    ensure_dirs()
    conn = sqlite3.connect(str(SESSIONS_DB))
    conn.row_factory = sqlite3.Row
    _init_db(conn)
    return conn


def _init_db(conn):
    conn.executescript("""
        CREATE TABLE IF NOT EXISTS sessions (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            project TEXT,
            created_at TEXT,
            updated_at TEXT
        );
        CREATE TABLE IF NOT EXISTS messages (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            session_id INTEGER,
            role TEXT,
            content TEXT,
            timestamp TEXT,
            FOREIGN KEY (session_id) REFERENCES sessions(id)
        );
        CREATE TABLE IF NOT EXISTS actions (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            session_id INTEGER,
            action_type TEXT,
            target TEXT,
            snapshot_path TEXT,
            timestamp TEXT,
            FOREIGN KEY (session_id) REFERENCES sessions(id)
        );
    """)
    conn.commit()


def create_session(project: str) -> int:
    conn = get_db()
    now = datetime.now().isoformat()
    cur = conn.execute(
        "INSERT INTO sessions (project, created_at, updated_at) VALUES (?, ?, ?)",
        (project, now, now)
    )
    conn.commit()
    sid = cur.lastrowid
    conn.close()
    return sid


def add_message(session_id: int, role: str, content: str):
    conn = get_db()
    conn.execute(
        "INSERT INTO messages (session_id, role, content, timestamp) VALUES (?, ?, ?, ?)",
        (session_id, role, content, datetime.now().isoformat())
    )
    conn.execute(
        "UPDATE sessions SET updated_at=? WHERE id=?",
        (datetime.now().isoformat(), session_id)
    )
    conn.commit()
    conn.close()


def get_messages(session_id: int) -> list:
    conn = get_db()
    rows = conn.execute(
        "SELECT role, content FROM messages WHERE session_id=? ORDER BY id",
        (session_id,)
    ).fetchall()
    conn.close()
    return [{"role": r["role"], "content": r["content"]} for r in rows]


def log_action(session_id: int, action_type: str, target: str, snapshot_path: str = ""):
    conn = get_db()
    conn.execute(
        "INSERT INTO actions (session_id, action_type, target, snapshot_path, timestamp) VALUES (?,?,?,?,?)",
        (session_id, action_type, target, snapshot_path, datetime.now().isoformat())
    )
    conn.commit()
    conn.close()


def get_last_action(session_id: int) -> dict | None:
    conn = get_db()
    row = conn.execute(
        "SELECT * FROM actions WHERE session_id=? ORDER BY id DESC LIMIT 1",
        (session_id,)
    ).fetchone()
    conn.close()
    return dict(row) if row else None


def list_sessions(project: str = None, limit: int = 10) -> list:
    conn = get_db()
    if project:
        rows = conn.execute(
            "SELECT * FROM sessions WHERE project=? ORDER BY id DESC LIMIT ?",
            (project, limit)
        ).fetchall()
    else:
        rows = conn.execute(
            "SELECT * FROM sessions ORDER BY id DESC LIMIT ?", (limit,)
        ).fetchall()
    conn.close()
    return [dict(r) for r in rows]


# ─── Stats ────────────────────────────────────────────────────────────────────

def load_stats() -> dict:
    ensure_dirs()
    if STATS_FILE.exists():
        with open(STATS_FILE) as f:
            return json.load(f)
    return {
        "files_edited": {},
        "bugs_found": 0,
        "commits_made": 0,
        "commands_run": 0,
        "ai_requests": 0,
        "models_used": {},
        "sessions_total": 0,
        "lines_written": 0,
    }


def save_stats(stats: dict):
    ensure_dirs()
    with open(STATS_FILE, "w") as f:
        json.dump(stats, f, indent=2)


def track(key: str, value=1, sub_key: str = None):
    stats = load_stats()
    if sub_key:
        if key not in stats:
            stats[key] = {}
        stats[key][sub_key] = stats[key].get(sub_key, 0) + value
    else:
        stats[key] = stats.get(key, 0) + value
    save_stats(stats)
