"""
SQLite database setup for CARL Control Panel.
Handles profiles and version history (snapshots).
"""
import sqlite3
from pathlib import Path
from datetime import datetime

# Database lives in the app's data directory
DB_PATH = Path(__file__).parent.parent / 'data' / 'carl_control_panel.db'


def get_connection() -> sqlite3.Connection:
    """Get a database connection with row factory."""
    DB_PATH.parent.mkdir(parents=True, exist_ok=True)
    conn = sqlite3.connect(str(DB_PATH))
    conn.row_factory = sqlite3.Row
    return conn


def init_database():
    """Initialize database schema if not exists."""
    conn = get_connection()
    cursor = conn.cursor()

    # Profiles table - workspace configurations
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS profiles (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            workspace_path TEXT NOT NULL,
            carl_subpath TEXT DEFAULT '.carl',
            is_active INTEGER DEFAULT 0,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            updated_at TEXT DEFAULT CURRENT_TIMESTAMP
        )
    ''')

    # Snapshots table - version history
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS snapshots (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            profile_id TEXT NOT NULL,
            timestamp TEXT DEFAULT CURRENT_TIMESTAMP,
            description TEXT,
            manifest_content TEXT NOT NULL,
            domains_content TEXT,
            FOREIGN KEY (profile_id) REFERENCES profiles(id)
        )
    ''')

    # App settings table
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS settings (
            key TEXT PRIMARY KEY,
            value TEXT
        )
    ''')

    conn.commit()
    conn.close()


def get_active_profile() -> dict | None:
    """Get the currently active profile."""
    conn = get_connection()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM profiles WHERE is_active = 1 LIMIT 1')
    row = cursor.fetchone()
    conn.close()

    if row:
        return dict(row)
    return None


def create_default_profile(workspace_path: str, carl_subpath: str = '.carl') -> str:
    """Create a default profile for the given workspace."""
    import uuid

    profile_id = str(uuid.uuid4())
    conn = get_connection()
    cursor = conn.cursor()

    # Deactivate any existing active profile
    cursor.execute('UPDATE profiles SET is_active = 0')

    # Create new profile
    cursor.execute('''
        INSERT INTO profiles (id, name, workspace_path, carl_subpath, is_active)
        VALUES (?, ?, ?, ?, 1)
    ''', (profile_id, 'Default', workspace_path, carl_subpath))

    conn.commit()
    conn.close()

    return profile_id


def get_setting(key: str, default: str = None) -> str | None:
    """Get an app setting by key."""
    conn = get_connection()
    cursor = conn.cursor()
    cursor.execute('SELECT value FROM settings WHERE key = ?', (key,))
    row = cursor.fetchone()
    conn.close()

    if row:
        return row['value']
    return default


def set_setting(key: str, value: str):
    """Set an app setting."""
    conn = get_connection()
    cursor = conn.cursor()
    cursor.execute('''
        INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)
    ''', (key, value))
    conn.commit()
    conn.close()


def get_all_profiles() -> list[dict]:
    """Get all workspace profiles."""
    conn = get_connection()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM profiles ORDER BY is_active DESC, name ASC')
    rows = cursor.fetchall()
    conn.close()
    return [dict(row) for row in rows]


def get_profile_by_id(profile_id: str) -> dict | None:
    """Get a specific profile by ID."""
    conn = get_connection()
    cursor = conn.cursor()
    cursor.execute('SELECT * FROM profiles WHERE id = ?', (profile_id,))
    row = cursor.fetchone()
    conn.close()
    return dict(row) if row else None


def create_profile(name: str, workspace_path: str, carl_subpath: str = '.carl', set_active: bool = True) -> str:
    """Create a new workspace profile."""
    import uuid

    profile_id = str(uuid.uuid4())
    conn = get_connection()
    cursor = conn.cursor()

    if set_active:
        # Deactivate any existing active profile
        cursor.execute('UPDATE profiles SET is_active = 0')

    cursor.execute('''
        INSERT INTO profiles (id, name, workspace_path, carl_subpath, is_active)
        VALUES (?, ?, ?, ?, ?)
    ''', (profile_id, name, workspace_path, carl_subpath, 1 if set_active else 0))

    conn.commit()
    conn.close()
    return profile_id


def switch_profile(profile_id: str) -> bool:
    """Switch to a different profile."""
    conn = get_connection()
    cursor = conn.cursor()

    # Deactivate all profiles
    cursor.execute('UPDATE profiles SET is_active = 0')

    # Activate the selected profile
    cursor.execute('UPDATE profiles SET is_active = 1 WHERE id = ?', (profile_id,))

    affected = cursor.rowcount
    conn.commit()
    conn.close()
    return affected > 0


def delete_profile(profile_id: str) -> bool:
    """Delete a workspace profile."""
    conn = get_connection()
    cursor = conn.cursor()

    cursor.execute('DELETE FROM profiles WHERE id = ?', (profile_id,))
    affected = cursor.rowcount

    conn.commit()
    conn.close()
    return affected > 0


def update_profile(profile_id: str, name: str = None, workspace_path: str = None) -> bool:
    """Update profile details."""
    conn = get_connection()
    cursor = conn.cursor()

    updates = []
    values = []

    if name is not None:
        updates.append('name = ?')
        values.append(name)
    if workspace_path is not None:
        updates.append('workspace_path = ?')
        values.append(workspace_path)

    if not updates:
        return False

    updates.append('updated_at = ?')
    values.append(datetime.now().isoformat())
    values.append(profile_id)

    cursor.execute(f'''
        UPDATE profiles SET {', '.join(updates)} WHERE id = ?
    ''', values)

    affected = cursor.rowcount
    conn.commit()
    conn.close()
    return affected > 0
