"""Shared SQLite database pentru toate datele auth-related (trusted devices, backup codes, email cache)."""
import aiosqlite
import logging
from pathlib import Path

logger = logging.getLogger(__name__)

DB_DIR = Path(__file__).parent.parent.parent / "backend" / "data"
DB_PATH = DB_DIR / "app.db"


async def get_db() -> aiosqlite.Connection:
    conn = await aiosqlite.connect(DB_PATH)
    conn.row_factory = aiosqlite.Row
    return conn


async def init_app_db():
    """Create all auth-related tables. Safe to call multiple times."""
    DB_DIR.mkdir(parents=True, exist_ok=True)
    async with aiosqlite.connect(DB_PATH) as db:
        await db.execute("PRAGMA journal_mode=WAL")
        await db.execute("PRAGMA busy_timeout=5000")
        await db.execute("PRAGMA foreign_keys = ON")

        # Telegram tables (delegate init from telegram/db/database.py)
        await db.execute("""CREATE TABLE IF NOT EXISTS telegram_users (
            telegram_user_id INTEGER PRIMARY KEY,
            username TEXT, first_name TEXT NOT NULL, last_name TEXT,
            oracle_username TEXT, oracle_server_id TEXT,
            jwt_token TEXT, jwt_refresh_token TEXT,
            token_expires_at TIMESTAMP, linked_at TIMESTAMP,
            last_active_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, is_active BOOLEAN DEFAULT 1
        )""")
        await db.execute("""CREATE TABLE IF NOT EXISTS telegram_auth_codes (
            code TEXT PRIMARY KEY, telegram_user_id INTEGER, oracle_username TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP NOT NULL,
            used BOOLEAN DEFAULT 0, used_at TIMESTAMP, server_id TEXT,
            FOREIGN KEY (telegram_user_id) REFERENCES telegram_users(telegram_user_id)
        )""")
        await db.execute("""CREATE TABLE IF NOT EXISTS telegram_sessions (
            session_id TEXT PRIMARY KEY, telegram_user_id INTEGER NOT NULL,
            conversation_state TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP NOT NULL,
            FOREIGN KEY (telegram_user_id) REFERENCES telegram_users(telegram_user_id)
        )""")
        await db.execute("""CREATE TABLE IF NOT EXISTS email_auth_codes (
            code TEXT PRIMARY KEY, email TEXT NOT NULL, oracle_username TEXT NOT NULL,
            telegram_user_id INTEGER NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            expires_at TIMESTAMP NOT NULL, used INTEGER DEFAULT 0, used_at TIMESTAMP,
            failed_attempts INTEGER DEFAULT 0,
            FOREIGN KEY (telegram_user_id) REFERENCES telegram_users(telegram_user_id)
        )""")

        # Trusted devices (migrated from JSON)
        await db.execute("""CREATE TABLE IF NOT EXISTS trusted_devices (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            token_hash TEXT NOT NULL UNIQUE,
            username TEXT NOT NULL,
            server_id TEXT,
            expires_at TIMESTAMP NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )""")

        # Backup codes (new)
        await db.execute("""CREATE TABLE IF NOT EXISTS backup_codes (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT NOT NULL,
            server_id TEXT,
            code_hash TEXT NOT NULL,
            used INTEGER DEFAULT 0,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            used_at TIMESTAMP
        )""")

        # Email-server cache (migrated from in-memory)
        await db.execute("""CREATE TABLE IF NOT EXISTS email_server_cache (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            email TEXT NOT NULL,
            server_id TEXT NOT NULL,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            UNIQUE(email, server_id)
        )""")

        # Indexes for telegram
        await db.execute("CREATE INDEX IF NOT EXISTS idx_auth_codes_telegram_user ON telegram_auth_codes(telegram_user_id)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_auth_codes_expires ON telegram_auth_codes(expires_at)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_sessions_telegram_user ON telegram_sessions(telegram_user_id)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_sessions_expires ON telegram_sessions(expires_at)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_email_auth_email ON email_auth_codes(email)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_email_auth_telegram_user ON email_auth_codes(telegram_user_id)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_email_auth_expires ON email_auth_codes(expires_at)")

        # Indexes for new tables
        await db.execute("CREATE INDEX IF NOT EXISTS idx_trusted_devices_user ON trusted_devices(username, server_id)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_trusted_devices_expires ON trusted_devices(expires_at)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_backup_codes_user ON backup_codes(username, server_id)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_email_cache_email ON email_server_cache(email)")
        await db.execute("CREATE INDEX IF NOT EXISTS idx_email_cache_server ON email_server_cache(server_id)")

        await db.commit()
    logger.info("[APP_DB] Database initialized successfully")
