"""Persistência cenários sandbox — Spec 035 (create-only audit trail)."""

from __future__ import annotations

import json
import sqlite3
import uuid
from datetime import datetime, timezone
from typing import Any


def _ts() -> str:
    return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")


def init_schema(conn: sqlite3.Connection) -> None:
    conn.executescript(
        """
        CREATE TABLE IF NOT EXISTS domain_console_scenarios (
            id TEXT PRIMARY KEY,
            domain TEXT NOT NULL,
            label TEXT NOT NULL DEFAULT '',
            plan_mock TEXT NOT NULL DEFAULT 'Business',
            baseline_accounts_json TEXT NOT NULL DEFAULT '[]',
            created_accounts_json TEXT NOT NULL DEFAULT '[]',
            status TEXT NOT NULL DEFAULT 'active',
            created_by TEXT NOT NULL DEFAULT '',
            created_at TEXT NOT NULL,
            updated_at TEXT NOT NULL
        );
        CREATE INDEX IF NOT EXISTS idx_dcs_domain ON domain_console_scenarios(domain);
        """
    )
    conn.commit()


def _row_to_dict(row: sqlite3.Row) -> dict[str, Any]:
    d = dict(row)
    d["baseline_accounts"] = json.loads(d.pop("baseline_accounts_json") or "[]")
    d["created_accounts"] = json.loads(d.pop("created_accounts_json") or "[]")
    return d


def list_scenarios(conn: sqlite3.Connection, limit: int = 50) -> list[dict[str, Any]]:
    rows = conn.execute(
        """
        SELECT * FROM domain_console_scenarios
        WHERE status = 'active'
        ORDER BY created_at DESC
        LIMIT ?
        """,
        (limit,),
    ).fetchall()
    return [_row_to_dict(r) for r in rows]


def get_scenario(conn: sqlite3.Connection, scenario_id: str) -> dict[str, Any] | None:
    row = conn.execute(
        "SELECT * FROM domain_console_scenarios WHERE id = ?", (scenario_id,)
    ).fetchone()
    return _row_to_dict(row) if row else None


def get_scenario_by_domain(conn: sqlite3.Connection, domain: str) -> dict[str, Any] | None:
    row = conn.execute(
        """
        SELECT * FROM domain_console_scenarios
        WHERE domain = ? AND status = 'active'
        ORDER BY created_at DESC LIMIT 1
        """,
        (domain.lower().strip(),),
    ).fetchone()
    return _row_to_dict(row) if row else None


def create_scenario(
    conn: sqlite3.Connection,
    *,
    domain: str,
    label: str,
    baseline_accounts: list[str],
    created_by: str,
    plan_mock: str = "Business",
) -> dict[str, Any]:
    scenario_id = str(uuid.uuid4())
    now = _ts()
    admin_email = f"admin@{domain}"
    created = [admin_email] if admin_email not in baseline_accounts else []
    conn.execute(
        """
        INSERT INTO domain_console_scenarios (
            id, domain, label, plan_mock, baseline_accounts_json,
            created_accounts_json, status, created_by, created_at, updated_at
        ) VALUES (?, ?, ?, ?, ?, ?, 'active', ?, ?, ?)
        """,
        (
            scenario_id,
            domain.lower().strip(),
            label,
            plan_mock,
            json.dumps(sorted(set(baseline_accounts)), ensure_ascii=False),
            json.dumps(created, ensure_ascii=False),
            created_by,
            now,
            now,
        ),
    )
    conn.commit()
    out = get_scenario(conn, scenario_id)
    assert out is not None
    return out


def append_created_account(conn: sqlite3.Connection, scenario_id: str, email: str) -> dict[str, Any]:
    row = get_scenario(conn, scenario_id)
    if not row:
        raise ValueError("cenário não encontrado")
    created = list(row["created_accounts"])
    email = email.lower().strip()
    if email not in created:
        created.append(email)
    now = _ts()
    conn.execute(
        """
        UPDATE domain_console_scenarios
        SET created_accounts_json = ?, updated_at = ?
        WHERE id = ?
        """,
        (json.dumps(created, ensure_ascii=False), now, scenario_id),
    )
    conn.commit()
    out = get_scenario(conn, scenario_id)
    assert out is not None
    return out
