"""Teste migrare defensiva coloane users (is_admin, email_verified).

TDD: RED -> implementare in _migrate -> GREEN.
"""

from __future__ import annotations

import sqlite3
import tempfile
from pathlib import Path

import pytest

from app.db import _migrate, init_db, get_connection
from app.config import get_settings


# ---------------------------------------------------------------------------
# Test 1: _migrate adauga is_admin si email_verified pe o tabela users minima
# ---------------------------------------------------------------------------

def test_migrate_adauga_is_admin_pe_users_veche() -> None:
    """Pe un DB cu tabela users creata fara is_admin/email_verified,
    _migrate trebuie sa adauge ambele coloane."""
    with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f:
        db_path = Path(f.name)

    conn = sqlite3.connect(str(db_path), isolation_level=None)
    conn.row_factory = sqlite3.Row
    conn.execute("PRAGMA journal_mode = WAL")
    conn.execute("PRAGMA foreign_keys = OFF")  # evitam FK checks pe schema minima

    # Tabela accounts minima (necesara pentru FK la users).
    # Trebuie sa aiba cui + rar_creds_enc + active ca _migrate sa nu crape
    # pe ALTER/CREATE INDEX care le refera inainte de blocul users.
    conn.execute("""
        CREATE TABLE accounts (
            id           INTEGER PRIMARY KEY AUTOINCREMENT,
            name         TEXT NOT NULL,
            cui          TEXT,
            active       INTEGER NOT NULL DEFAULT 1,
            rar_creds_enc TEXT
        )
    """)
    conn.execute("INSERT INTO accounts (id, name) VALUES (1, 'default')")

    # Tabela submissions minima (necesara pentru _migrate -- coloane submissions)
    conn.execute("""
        CREATE TABLE submissions (
            id               INTEGER PRIMARY KEY AUTOINCREMENT,
            idempotency_key  TEXT NOT NULL UNIQUE,
            account_id       INTEGER,
            status           TEXT NOT NULL DEFAULT 'queued',
            payload_json     TEXT NOT NULL,
            rar_creds_enc    TEXT,
            rar_status_code  INTEGER,
            rar_error        TEXT,
            id_prezentare    INTEGER,
            retry_count      INTEGER NOT NULL DEFAULT 0,
            next_attempt_at  TEXT,
            sending_since    TEXT,
            purge_after      TEXT,
            batch_id         INTEGER,
            row_index        INTEGER,
            created_at       TEXT NOT NULL DEFAULT (datetime('now')),
            updated_at       TEXT NOT NULL DEFAULT (datetime('now'))
        )
    """)

    # Tabela users MINIMA: fara is_admin, fara email_verified
    conn.execute("""
        CREATE TABLE users (
            id              INTEGER PRIMARY KEY AUTOINCREMENT,
            account_id      INTEGER NOT NULL,
            email           TEXT NOT NULL UNIQUE,
            password_hash   TEXT NOT NULL,
            salt            TEXT NOT NULL,
            scrypt_params   TEXT NOT NULL,
            created_at      TEXT NOT NULL DEFAULT (datetime('now'))
        )
    """)

    try:
        # Rulam migrarea
        _migrate(conn)

        # Verificam ca ambele coloane au fost adaugate
        cols = {r["name"] for r in conn.execute("PRAGMA table_info(users)").fetchall()}
        assert "is_admin" in cols, f"is_admin lipseste dupa migrare; coloane prezente: {cols}"
        assert "email_verified" in cols, f"email_verified lipseste dupa migrare; coloane prezente: {cols}"
    finally:
        conn.close()
        db_path.unlink(missing_ok=True)


# ---------------------------------------------------------------------------
# Test 2: _migrate este idempotent pe un DB initializat normal cu init_db()
# ---------------------------------------------------------------------------

def test_migrate_idempotent_pe_users_curenta(tmp_path: pytest.TempPathFactory, monkeypatch: pytest.MonkeyPatch) -> None:
    """Pe un DB initializat normal, re-apelarea _migrate nu ridica exceptie
    si coloanele is_admin/email_verified raman prezente."""
    db_file = tmp_path / "test_idem.db"
    monkeypatch.setenv("AUTOPASS_DB_PATH", str(db_file))

    # Resetam settings-ul cached ca sa preia noul AUTOPASS_DB_PATH
    get_settings.cache_clear()  # type: ignore[attr-defined]

    try:
        # Initializare normala
        init_db()

        # Re-apelam _migrate direct (idempotenta)
        conn = get_connection()
        try:
            _migrate(conn)  # nu trebuie sa ridice

            cols = {r["name"] for r in conn.execute("PRAGMA table_info(users)").fetchall()}
            assert "is_admin" in cols
            assert "email_verified" in cols
        finally:
            conn.close()
    finally:
        get_settings.cache_clear()  # type: ignore[attr-defined]
