"""API sandbox — Área Gerente create-only (Spec 035)."""

from __future__ import annotations

import sqlite3
from typing import Any

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field

from app import auth, domain_console_sandbox as sandbox
from app.permissions import can_manage_vm112_domains

router = APIRouter(prefix="/api/v1/domain-console/sandbox", tags=["domain-console-sandbox"])


def _require_sandbox(user: auth.DeskUser = Depends(auth.get_current_user)) -> auth.DeskUser:
    if not can_manage_vm112_domains(user.role):
        raise HTTPException(403, "Sem permissão sandbox domain console")
    return user


def _db() -> sqlite3.Connection:
    from app.main import db

    return db()


class CreateScenarioBody(BaseModel):
    label: str = Field(..., min_length=2, max_length=120)
    domain: str | None = None
    slug: str | None = Field(None, max_length=40)
    plan_mock: str = "Business"
    admin_password: str | None = Field(None, min_length=8)


class AddAccountBody(BaseModel):
    local_part: str = Field(..., min_length=1, max_length=64)
    display_name: str = Field("", max_length=120)
    password: str | None = Field(None, min_length=8)


@router.get("/config")
def sandbox_config(_user: auth.DeskUser = Depends(_require_sandbox)):
    return {
        "enabled": sandbox.SANDBOX_ENABLED,
        "mode": "create-only",
        "delete_blocked": True,
        "domain_prefix": sandbox.SANDBOX_DOMAIN_PREFIX,
        "domain_suffix": sandbox.SANDBOX_ALLOWED_SUFFIX,
        "suggested_domain": sandbox.suggest_scenario_domain(),
        "protected_domains": sorted(sandbox.PROTECTED_DOMAINS),
    }


@router.get("/domains")
def list_domains_readonly(
    q: str = "",
    _user: auth.DeskUser = Depends(_require_sandbox),
):
    return sandbox.list_domains_readonly(q)


@router.get("/domains/{domain}")
def get_domain_readonly(
    domain: str,
    _user: auth.DeskUser = Depends(_require_sandbox),
):
    return sandbox.fetch_domain_readonly(domain)


@router.get("/scenarios")
def list_scenarios(
    user: auth.DeskUser = Depends(_require_sandbox),
):
    from app.domain_console_sandbox_store import init_schema, list_scenarios as ls

    conn = _db()
    init_schema(conn)
    return {"scenarios": ls(conn), "delete_blocked": True}


@router.post("/scenarios")
def create_scenario(
    body: CreateScenarioBody,
    user: auth.DeskUser = Depends(_require_sandbox),
):
    from app.domain_console_sandbox_store import init_schema

    conn = _db()
    init_schema(conn)
    try:
        return sandbox.create_scenario(
            conn,
            label=body.label,
            domain=body.domain,
            slug=body.slug,
            created_by=user.username,
            plan_mock=body.plan_mock,
            admin_password=body.admin_password,
        )
    except sandbox.SandboxForbidden as e:
        raise HTTPException(403, str(e)) from e
    except sandbox.SandboxError as e:
        raise HTTPException(400, str(e)) from e


@router.get("/scenarios/{scenario_id}/state")
def scenario_state(
    scenario_id: str,
    _user: auth.DeskUser = Depends(_require_sandbox),
):
    from app.domain_console_sandbox_store import init_schema

    conn = _db()
    init_schema(conn)
    try:
        return sandbox.build_console_state(conn, scenario_id)
    except sandbox.SandboxError as e:
        raise HTTPException(404, str(e)) from e


@router.post("/scenarios/{scenario_id}/accounts")
def add_account(
    scenario_id: str,
    body: AddAccountBody,
    _user: auth.DeskUser = Depends(_require_sandbox),
):
    from app.domain_console_sandbox_store import init_schema

    conn = _db()
    init_schema(conn)
    try:
        return sandbox.add_account_to_scenario(
            conn,
            scenario_id=scenario_id,
            local_part=body.local_part,
            display_name=body.display_name,
            password=body.password,
        )
    except sandbox.SandboxForbidden as e:
        raise HTTPException(403, str(e)) from e
    except sandbox.SandboxError as e:
        raise HTTPException(400, str(e)) from e


@router.delete("/scenarios/{scenario_id}")
def block_delete_scenario(scenario_id: str, _user: auth.DeskUser = Depends(_require_sandbox)):
    try:
        sandbox.assert_no_delete(f"delete scenario {scenario_id}")
    except sandbox.SandboxForbidden as e:
        raise HTTPException(403, str(e)) from e
    raise HTTPException(403, "delete bloqueado")


@router.delete("/scenarios/{scenario_id}/accounts/{email}")
def block_delete_account(
    scenario_id: str,
    email: str,
    _user: auth.DeskUser = Depends(_require_sandbox),
):
    try:
        sandbox.assert_no_delete(f"delete account {email}")
    except sandbox.SandboxForbidden as e:
        raise HTTPException(403, str(e)) from e
    raise HTTPException(403, "delete bloqueado")


@router.post("/scenarios/{scenario_id}/purge")
def block_purge_scenario(scenario_id: str, _user: auth.DeskUser = Depends(_require_sandbox)):
    try:
        sandbox.assert_no_delete(f"purge scenario {scenario_id}")
    except sandbox.SandboxForbidden as e:
        raise HTTPException(403, str(e)) from e
    raise HTTPException(403, "purge bloqueado")
