from __future__ import annotations

import sqlite3

from backend.database.migrations.runner import Migration


def upgrade(connection: sqlite3.Connection) -> None:
    statements = (
        """
        CREATE TABLE users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT NOT NULL,
            username_key TEXT NOT NULL UNIQUE,
            password_hash TEXT NOT NULL,
            is_admin INTEGER NOT NULL DEFAULT 0 CHECK (is_admin IN (0, 1)),
            status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'disabled')),
            created_at TEXT NOT NULL,
            updated_at TEXT NOT NULL
        )
        """,
        """
        CREATE TABLE memberships (
            user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
            state TEXT NOT NULL DEFAULT 'inactive'
                CHECK (state IN ('inactive', 'active', 'disabled')),
            expires_at TEXT,
            is_permanent INTEGER NOT NULL DEFAULT 0 CHECK (is_permanent IN (0, 1)),
            daily_llm_limit INTEGER NOT NULL DEFAULT 50
                CHECK (daily_llm_limit BETWEEN 1 AND 1000),
            updated_at TEXT NOT NULL,
            updated_by INTEGER REFERENCES users(id) ON DELETE SET NULL
        )
        """,
        """
        CREATE TABLE sessions (
            token_hash TEXT PRIMARY KEY,
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            csrf_hash TEXT NOT NULL,
            created_at TEXT NOT NULL,
            expires_at TEXT NOT NULL,
            last_seen_at TEXT NOT NULL
        )
        """,
        "CREATE INDEX sessions_user_id_idx ON sessions(user_id)",
        "CREATE INDEX sessions_expires_at_idx ON sessions(expires_at)",
        """
        CREATE TABLE birth_profiles (
            user_id INTEGER PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
            encrypted_payload TEXT NOT NULL,
            created_at TEXT NOT NULL,
            updated_at TEXT NOT NULL
        )
        """,
        """
        CREATE TABLE llm_usage_daily (
            user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
            usage_date TEXT NOT NULL,
            successful_calls INTEGER NOT NULL DEFAULT 0 CHECK (successful_calls >= 0),
            updated_at TEXT NOT NULL,
            PRIMARY KEY (user_id, usage_date)
        )
        """,
        """
        CREATE TABLE system_credentials (
            name TEXT PRIMARY KEY,
            encrypted_value TEXT NOT NULL,
            updated_at TEXT NOT NULL,
            updated_by INTEGER NOT NULL REFERENCES users(id) ON DELETE RESTRICT
        )
        """,
    )
    for statement in statements:
        connection.execute(statement)


def downgrade(connection: sqlite3.Connection) -> None:
    for table in (
        "system_credentials",
        "llm_usage_daily",
        "birth_profiles",
        "sessions",
        "memberships",
        "users",
    ):
        connection.execute(f"DROP TABLE {table}")


MIGRATION = Migration(
    version=1,
    name="create_accounts",
    signature="accounts:v1:users-memberships-sessions-profiles-usage-credentials",
    upgrade=upgrade,
    downgrade=downgrade,
)
