"""Rotas libertação ACCOUNT_EXISTS — Spec 022."""

from __future__ import annotations

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

from app import auth, carbonio_release_store, vm112_domains
from app.permissions import can_read_tickets

router = APIRouter(prefix="/api/v1/carbonio-blocks", tags=["carbonio-release"])


class ResolveBlockBody(BaseModel):
    confirm_email: str = Field(..., min_length=5)
    password: str = Field(..., min_length=1)


def _require_ticket_reader(user: auth.DeskUser = Depends(auth.get_current_user)) -> auth.DeskUser:
    if not can_read_tickets(user.role):
        raise HTTPException(403, "permissão insuficiente")
    return user


def _verify_user_password(conn, username: str, password: str) -> bool:
    row = conn.execute(
        "SELECT password_hash FROM desk_users WHERE username = ? AND active = 1",
        (username,),
    ).fetchone()
    if not row or not row["password_hash"]:
        return False
    return auth.verify_password(password, row["password_hash"])


@router.get("")
def list_carbonio_blocks(
    status: str = Query("pending"),
    session_id: str = "",
    ticket_id: int | None = None,
    limit: int = Query(100, ge=1, le=500),
    user: auth.DeskUser = Depends(_require_ticket_reader),
):
    conn = auth.db()
    try:
        return carbonio_release_store.list_blocks(
            conn,
            status=status or "all",
            session_id=session_id.strip() or None,
            ticket_id=ticket_id,
            limit=limit,
        )
    finally:
        conn.close()


@router.get("/{block_id}")
def get_carbonio_block(
    block_id: int,
    user: auth.DeskUser = Depends(_require_ticket_reader),
):
    conn = auth.db()
    try:
        block = carbonio_release_store.get_block(conn, block_id)
    finally:
        conn.close()
    if not block:
        raise HTTPException(404, "bloqueio não encontrado")
    return block


@router.post("/{block_id}/resolve")
def resolve_carbonio_block(
    block_id: int,
    body: ResolveBlockBody,
    user: auth.DeskUser = Depends(_require_ticket_reader),
):
    conn = auth.db()
    try:
        block = carbonio_release_store.get_block(conn, block_id)
        if not block:
            raise HTTPException(404, "bloqueio não encontrado")
        if block["status"] == "resolved":
            raise HTTPException(409, f"Já resolvido por {block.get('resolved_by') or 'outro técnico'}")
        if body.confirm_email.lower().strip() != block["email"].lower():
            raise HTTPException(400, "E-mail de confirmação não coincide")
        if not _verify_user_password(conn, user.username, body.password):
            raise HTTPException(403, "Senha incorrecta")

        try:
            vm_result = vm112_domains.delete_carbonio_account(block["email"])
        except Exception as e:
            raise HTTPException(502, f"VM112/Carbonio: {e}") from e

        try:
            resolved = carbonio_release_store.resolve_block(
                conn,
                block_id,
                resolved_by=user.username,
                note=vm_result.get("message", "zmprov da"),
            )
        except ValueError as e:
            if str(e) == "already_resolved":
                raise HTTPException(409, "Outro técnico já resolveu este bloqueio") from e
            raise HTTPException(404, "Bloqueio indisponível") from e

        if block.get("ticket_id"):
            carbonio_release_store.append_ticket_resolution_note(
                conn,
                int(block["ticket_id"]),
                email=block["email"],
                by=user.username,
            )
        return {
            "ok": True,
            "block": resolved,
            "vm112": vm_result,
            "message": f"Conta {block['email']} removida do Carbonio. Peça ao cliente para repetir «Criar conta» no wizard.",
        }
    finally:
        conn.close()
