"""
Dialogo para anular una venta activa.

El PIN de supervisor ya fue validado en SupervisorPinDialog.
Este dialogo solo muestra la info de la pulsera y confirma la anulacion.

Flujo:
  1. Muestra info de la pulsera (paquete, cliente).
  2. Clic ANULAR VENTA -> llama api.anular_venta() en hilo.
  3. Exito: muestra supervisor_nombre y quita pulsera del tracker.
  4. Error: muestra mensaje, permite reintentar.

Diseño: popup flotante always-on-top, sin bordes del OS (estilo ICEBERG).
"""
import threading
import customtkinter as ctk
from typing import Optional, Callable
import api
import wristband_tracker
from ui.kb_shortcuts import bind_entry

# ---------------------------------------------------------------------------
# Colores ICEBERG
# ---------------------------------------------------------------------------
_BG_CARD     = "#0f1228"
_ACCENT_RED  = "#f44336"
_ACCENT_DIM  = "#7f0000"
_BTN_OK      = "#b71c1c"
_BTN_OK_HV   = "#7f0000"
_BTN_CANCEL  = "transparent"
_BTN_CANCEL_HV = "#1a2440"
_TEXT_DIM    = "#666677"
_TEXT_MID    = "#9999aa"
_ERR_RED     = "#f44336"
_OK_GREEN    = "#4caf50"
_CYAN        = "#4fc3f7"
_TOP_BAR     = "#b71c1c"
_SEPARATOR   = "#1a2440"
_INFO_BG     = "#111530"
_INFO_BORDER = "#3a1a1a"


class AnularDialog(ctk.CTkToplevel):
    """
    Popup flotante ICEBERG para anular una venta activa.
    El PIN/motivo ya fueron validados en SupervisorPinDialog.
    entry:   dict de wristband_tracker (con session_id, package_name, name, id).
    cashier: cajero actual.
    supervisor: nombre del supervisor (del voucher_data).
    motivo: motivo de anulacion (del voucher_data).
    on_done: llamado con result dict si la anulacion es exitosa.
    """

    def __init__(
        self,
        parent,
        entry: dict,
        cashier: str = "caja1",
        supervisor: str = "",
        motivo: str = "",
        on_done: Optional[Callable] = None,
    ):
        super().__init__(parent)
        self._entry      = entry
        self._cashier    = cashier
        self._supervisor = supervisor
        self._motivo     = motivo
        self._on_done    = on_done
        self._result     = None
        self._waiting    = False

        # Ventana sin bordes del OS, siempre encima
        self.overrideredirect(True)
        self.attributes("-topmost", True)
        self.configure(fg_color=_BG_CARD)

        # Tamaño y posicion centrada sobre el padre
        self._win_w = 440
        self._win_h = 420
        self.geometry(f"{self._win_w}x{self._win_h}")
        self._center_on_parent(parent)

        # Grab modal
        self.grab_set()
        self.focus_force()

        # Card principal
        self._card = ctk.CTkFrame(
            self,
            fg_color=_BG_CARD,
            corner_radius=0,
            border_width=2,
            border_color=_ACCENT_DIM,
        )
        self._card.pack(fill="both", expand=True)

        # Bind Escape para cancelar
        self.bind("<Escape>", lambda e: self._close())
        self.bind("<Return>", lambda e: self._on_submit())

        # Permitir mover la ventana arrastrando
        self._drag_data = {"x": 0, "y": 0}
        self._card.bind("<Button-1>", self._start_drag)
        self._card.bind("<B1-Motion>", self._do_drag)

        self._build()

    # ------------------------------------------------------------------
    # Posicion y arrastre
    # ------------------------------------------------------------------

    def _center_on_parent(self, parent):
        self.update_idletasks()
        px = parent.winfo_rootx() + parent.winfo_width() // 2
        py = parent.winfo_rooty() + parent.winfo_height() // 2
        x = px - self._win_w // 2
        y = py - self._win_h // 2
        self.geometry(f"{self._win_w}x{self._win_h}+{x}+{y}")

    def _start_drag(self, event):
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y

    def _do_drag(self, event):
        x = self.winfo_x() + (event.x - self._drag_data["x"])
        y = self.winfo_y() + (event.y - self._drag_data["y"])
        self.geometry(f"+{x}+{y}")

    # ------------------------------------------------------------------
    # UI
    # ------------------------------------------------------------------

    def _build(self):
        card = self._card

        # Barra roja superior
        bar = ctk.CTkFrame(card, fg_color=_TOP_BAR, height=4, corner_radius=0)
        bar.pack(fill="x", side="top")

        # Icono y titulo
        ctk.CTkLabel(
            card, text="\u26D4",
            font=ctk.CTkFont(size=36),
        ).pack(pady=(16, 0))

        ctk.CTkLabel(
            card, text="Anular Venta",
            font=ctk.CTkFont(size=20, weight="bold"),
            text_color=_ACCENT_RED,
        ).pack(pady=(4, 8))

        # Info de la pulsera
        info_frame = ctk.CTkFrame(
            card, fg_color=_INFO_BG, corner_radius=6,
            border_width=1, border_color=_INFO_BORDER,
        )
        info_frame.pack(fill="x", padx=30, pady=(0, 10))

        name = self._entry.get("name", "").strip() or "(sin nombre)"
        pkg  = self._entry.get("package_name", "")
        code = self._entry.get("code", "")
        ref  = self._entry.get("reference", "").strip()

        ctk.CTkLabel(
            info_frame, text=name,
            font=ctk.CTkFont(size=14, weight="bold"), text_color="#e0e0e0",
        ).pack(anchor="w", padx=14, pady=(10, 2))
        detail = f"{pkg}  \u00b7  {code}" + (f"  \u00b7  Ref: {ref}" if ref else "")
        ctk.CTkLabel(
            info_frame, text=detail,
            font=ctk.CTkFont(size=11), text_color=_TEXT_DIM,
        ).pack(anchor="w", padx=14, pady=(0, 10))

        # Info de autorizacion
        if self._supervisor:
            auth_frame = ctk.CTkFrame(card, fg_color=_INFO_BG, corner_radius=6)
            auth_frame.pack(fill="x", padx=30, pady=(0, 10))

            ctk.CTkLabel(
                auth_frame,
                text=f"Autorizado por:  {self._supervisor}",
                font=ctk.CTkFont(size=11),
                text_color=_ACCENT_RED,
            ).pack(anchor="w", padx=12, pady=(8, 2))

            if self._motivo:
                motivo_display = self._motivo if len(self._motivo) <= 50 else self._motivo[:47] + "..."
                ctk.CTkLabel(
                    auth_frame,
                    text=f"Motivo:  {motivo_display}",
                    font=ctk.CTkFont(size=11),
                    text_color=_TEXT_MID,
                ).pack(anchor="w", padx=12, pady=(0, 8))

        # Separador
        ctk.CTkFrame(card, fg_color=_SEPARATOR, height=1, corner_radius=0).pack(
            fill="x", padx=30, pady=(0, 12)
        )

        # Boton anular
        self._btn_submit = ctk.CTkButton(
            card, text="ANULAR VENTA",
            font=ctk.CTkFont(size=14, weight="bold"), height=50,
            corner_radius=10, fg_color=_BTN_OK, hover_color=_BTN_OK_HV,
            command=self._on_submit,
        )
        self._btn_submit.pack(fill="x", padx=30, pady=(0, 6))

        # Estado / resultado
        self._lbl_status = ctk.CTkLabel(
            card, text="",
            font=ctk.CTkFont(size=13), wraplength=380, justify="center",
        )
        self._lbl_status.pack(pady=(0, 4))

        # Cancelar (ghost button)
        ctk.CTkButton(
            card, text="Cancelar",
            font=ctk.CTkFont(size=12),
            fg_color=_BTN_CANCEL, hover_color=_BTN_CANCEL_HV,
            text_color=_TEXT_DIM, height=30,
            command=self._close,
        ).pack(pady=(0, 10))

    # ------------------------------------------------------------------
    # Flujo
    # ------------------------------------------------------------------

    def _on_submit(self):
        if self._waiting:
            return

        self._waiting = True
        self._btn_submit.configure(
            state="disabled", text="Anulando...", fg_color="#424242",
        )
        self._lbl_status.configure(text="Procesando...", text_color=_CYAN)

        session_id = self._entry.get("session_id", "")
        threading.Thread(
            target=self._do_anular,
            args=(session_id,),
            daemon=True,
        ).start()

    def _do_anular(self, session_id: str):
        result = api.anular_venta(
            session_id=session_id,
            cashier=self._cashier,
            motivo=self._motivo,
            supervisor=self._supervisor,
        )
        self.after(0, lambda: self._on_result(result))

    def _on_result(self, result: dict):
        self._waiting = False

        if result.get("error"):
            self._btn_submit.configure(
                state="normal", text="ANULAR VENTA", fg_color=_BTN_OK,
            )
            self._lbl_status.configure(
                text=f"Error: {result['error']}", text_color=_ERR_RED,
            )
            return

        if result.get("status") == "ok":
            self._show_success(result)

        elif result.get("status") == "error":
            self._btn_submit.configure(
                state="normal", text="ANULAR VENTA", fg_color=_BTN_OK,
            )
            msg = result.get("message", "Error al anular.")
            self._lbl_status.configure(text=msg, text_color=_ERR_RED)

        else:
            self._btn_submit.configure(
                state="normal", text="ANULAR VENTA", fg_color=_BTN_OK,
            )
            self._lbl_status.configure(
                text="Respuesta inesperada del servidor.", text_color=_ERR_RED,
            )

    # ------------------------------------------------------------------
    # Pantalla de exito
    # ------------------------------------------------------------------

    def _show_success(self, result: dict):
        # Marcar como anulada (NO quitar — la pulsera sigue activa fisicamente)
        wristband_tracker.mark_anulada(self._entry["id"])

        # Limpiar card
        for widget in self._card.winfo_children():
            widget.destroy()

        # Barra roja
        ctk.CTkFrame(self._card, fg_color=_TOP_BAR, height=4, corner_radius=0).pack(
            fill="x", side="top"
        )

        # Checkmark
        ctk.CTkLabel(
            self._card, text="\u2713",
            font=ctk.CTkFont(size=52, weight="bold"),
            text_color=_OK_GREEN,
        ).pack(pady=(40, 8))

        ctk.CTkLabel(
            self._card, text="Venta anulada!",
            font=ctk.CTkFont(size=20, weight="bold"),
            text_color=_OK_GREEN,
        ).pack(pady=(0, 6))

        sup = result.get("supervisor_nombre", "") or self._supervisor
        if sup:
            ctk.CTkLabel(
                self._card, text=f"Autorizado por: {sup}",
                font=ctk.CTkFont(size=12),
                text_color=_TEXT_MID,
            ).pack(pady=(0, 4))

        # Borde verde
        self._card.configure(border_color=_OK_GREEN)

        if self._on_done:
            self._on_done(result)
        self.after(2500, self._close)

    # ------------------------------------------------------------------

    def _close(self):
        if self._waiting:
            return
        try:
            self.grab_release()
        except Exception:
            pass
        self.destroy()
