"""SSE stream — purge domínio VM112 + Desk (Spec 017 Fase 2)."""

from __future__ import annotations

import json
import queue
import threading
import time
from collections.abc import Iterator
from typing import Any

from app import auth, vm112_domains


def _sse(payload: dict[str, Any]) -> str:
    return f"data: {json.dumps(payload, ensure_ascii=False)}\n\n"


def purge_sse_generator(domain: str, root_password: str, username: str) -> Iterator[str]:
    domain = domain.lower().strip()

    conn = auth.db()
    try:
        if not vm112_domains.verify_root_password(conn, root_password):
            yield _sse({
                "type": "error",
                "step": vm112_domains._timeline_entry("Validação Root", "fail", "Senha Root incorrecta"),
            })
            return
    finally:
        conn.close()

    yield _sse({"type": "step", "step": vm112_domains._timeline_entry("Validação Root + confirmação", "ok")})
    yield _sse({
        "type": "step",
        "step": vm112_domains._timeline_entry(
            "Purge VM112 — em execução",
            "running",
            "Carbonio, site, portal, Cloudflare, Traefik…",
        ),
    })

    vm112_result: dict[str, Any] = {"ok": False}
    for kind, payload in vm112_domains.purge_vm112_with_poll(domain, poll_interval=2.0):
        if kind == "step":
            yield _sse({"type": "step", "step": payload, "phase": "vm112"})
        elif kind == "heartbeat":
            yield _sse({
                "type": "heartbeat",
                "elapsed": payload.get("elapsed", 0),
                "label": "Purge VM112 — em execução",
            })
        elif kind == "final":
            vm112_result = payload
            if not vm112_result.get("ok", False):
                yield _sse({
                    "type": "error",
                    "step": vm112_domains._timeline_entry(
                        "Purge VM112",
                        "fail",
                        str(vm112_result.get("error") or "falhou"),
                    ),
                })
                return
            break

    conn = auth.db()
    desk_counts: dict[str, int] = {}
    try:
        domain_l = domain.lower().strip()
        like = f"%{domain_l}%"
        desk_steps = (
            ("Desk — webhook_events", "webhook_events", "DELETE FROM webhook_events WHERE payload LIKE ?", (like,)),
            ("Desk — tickets", "tickets", "DELETE FROM tickets WHERE subject LIKE ? OR payload LIKE ?", (like, like)),
            ("Desk — audit_domains", "audit_domains", "DELETE FROM audit_domains WHERE domain = ?", (domain_l,)),
            ("Desk — assist_sessions", "assist_sessions", "DELETE FROM assist_sessions WHERE domain = ?", (domain_l,)),
            ("Desk — audit_checks", "audit_checks", "DELETE FROM audit_checks WHERE domain = ?", (domain_l,)),
        )
        for label, key, sql, params in desk_steps:
            yield _sse({"type": "step", "step": vm112_domains._timeline_entry(label, "running")})
            n = conn.execute(sql, params).rowcount
            desk_counts[key] = n
            yield _sse({
                "type": "step",
                "step": vm112_domains._timeline_entry(label, "ok", f"{n} registo(s) removido(s)"),
                "phase": "desk",
            })
        conn.commit()
    finally:
        conn.close()

    total_desk = sum(desk_counts.values())
    done_step = vm112_domains._timeline_entry("Purge concluído", "ok", f"Desk: {total_desk} registo(s)")
    yield _sse({
        "type": "done",
        "step": done_step,
        "domain": domain,
        "vm112": vm112_result,
        "desk": desk_counts,
        "by": username,
    })
