"""
Dialogo de autenticacion elevada para acceder a Configuracion.

Se muestra cuando un cajero sin permisos suficientes intenta entrar
al modo configuracion. Pide credenciales de un usuario autorizado
(sub-sesion) sin cerrar ni modificar la sesion actual del cajero.
"""
import threading
import customtkinter as ctk
from typing import Callable, Optional
from ui.kb_shortcuts import bind_entry


class ConfigAuthDialog(ctk.CTkFrame):
    """
    Overlay que pide usuario y contraseña de un cajero autorizado.

    Si las credenciales son validas y el usuario tiene permisos de
    configuracion (lb_paquetes o all), invoca on_success.
    La sesion principal NO se modifica.
    """

    def __init__(
        self,
        parent,
        on_success: Optional[Callable] = None,
        on_cancel: Optional[Callable] = None,
    ):
        super().__init__(parent, fg_color="#08081a")
        self._on_success = on_success
        self._on_cancel = on_cancel

        self.place(relx=0, rely=0, relwidth=1, relheight=1)
        self.lift()

        # Card centrada
        card = ctk.CTkFrame(
            self, width=420, height=380,
            fg_color="#0f1d32",
            corner_radius=16,
            border_width=2,
            border_color="#1a3050",
        )
        card.place(relx=0.5, rely=0.45, anchor="center")
        card.pack_propagate(False)

        # Icono de advertencia
        ctk.CTkLabel(
            card, text="🔒",
            font=ctk.CTkFont(size=36),
        ).pack(pady=(28, 4))

        # Titulo
        ctk.CTkLabel(
            card, text="Acceso restringido",
            font=ctk.CTkFont(size=18, weight="bold"),
            text_color="#ffab00",
        ).pack(pady=(0, 4))

        # Subtitulo
        ctk.CTkLabel(
            card,
            text="Ingresa las credenciales de un usuario\ncon permisos de configuracion.",
            font=ctk.CTkFont(size=12),
            text_color="#7a8ba8",
            justify="center",
        ).pack(pady=(0, 16))

        # Campo usuario
        ctk.CTkLabel(
            card, text="Usuario",
            font=ctk.CTkFont(size=11),
            text_color="#7a8ba8",
            anchor="w",
        ).pack(fill="x", padx=48, pady=(0, 2))

        self._entry_user = ctk.CTkEntry(
            card, width=320, height=38,
            placeholder_text="Usuario autorizado",
            font=ctk.CTkFont(size=13),
        )
        self._entry_user.pack(padx=48, pady=(0, 10))
        bind_entry(self._entry_user)

        # Campo contraseña
        ctk.CTkLabel(
            card, text="Contraseña",
            font=ctk.CTkFont(size=11),
            text_color="#7a8ba8",
            anchor="w",
        ).pack(fill="x", padx=48, pady=(0, 2))

        self._entry_pass = ctk.CTkEntry(
            card, width=320, height=38,
            placeholder_text="Contraseña",
            show="●",
            font=ctk.CTkFont(size=13),
        )
        self._entry_pass.pack(padx=48, pady=(0, 6))
        bind_entry(self._entry_pass)

        # Label de error
        self._lbl_error = ctk.CTkLabel(
            card, text="",
            font=ctk.CTkFont(size=11),
            text_color="#ff4444",
        )
        self._lbl_error.pack(pady=(0, 8))

        # Botones
        btn_row = ctk.CTkFrame(card, fg_color="transparent")
        btn_row.pack(pady=(0, 20))

        ctk.CTkButton(
            btn_row, text="Cancelar",
            width=110, height=36, corner_radius=8,
            fg_color="#152540", hover_color="#1a3050",
            text_color="#7a8ba8",
            font=ctk.CTkFont(size=13),
            command=self._close,
        ).pack(side="left", padx=(0, 10))

        self._btn_auth = ctk.CTkButton(
            btn_row, text="Ingresar",
            width=130, height=36, corner_radius=8,
            fg_color="#00d4ff", hover_color="#00a8cc",
            text_color="#060b18",
            font=ctk.CTkFont(size=13, weight="bold"),
            command=self._authenticate,
        )
        self._btn_auth.pack(side="left")

        # Enter para enviar
        self._entry_pass.bind("<Return>", lambda e: self._authenticate())
        self._entry_user.bind("<Return>", lambda e: self._entry_pass.focus())

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

        # Foco al campo usuario
        self.after(100, self._entry_user.focus)

    # ------------------------------------------------------------------
    # Autenticacion
    # ------------------------------------------------------------------

    def _authenticate(self):
        username = self._entry_user.get().strip()
        password = self._entry_pass.get().strip()

        if not username or not password:
            self._lbl_error.configure(text="Ingresa usuario y contraseña.")
            return

        self._btn_auth.configure(text="Verificando...", state="disabled")
        self._lbl_error.configure(text="")

        def _do_auth():
            import auth
            import session as sess

            venue_id = sess.get_venue_id()
            result = auth.authenticate(username, password, venue_id)

            self.after(0, lambda: self._handle_result(result))

        threading.Thread(target=_do_auth, daemon=True).start()

    def _handle_result(self, result):
        self._btn_auth.configure(text="Ingresar", state="normal")

        if result is None:
            self._lbl_error.configure(text="Credenciales invalidas.")
            return

        if isinstance(result, dict) and result.get("error"):
            err = result["error"]
            if err == "no_venue_access":
                self._lbl_error.configure(text="Este usuario no tiene acceso a esta sede.")
            elif err == "sin_conexion":
                self._lbl_error.configure(text="Sin conexion. Intenta mas tarde.")
            else:
                self._lbl_error.configure(
                    text=result.get("detail", "Error de autenticacion."),
                )
            return

        # Autenticacion exitosa — verificar permisos
        perms = result.get("permissions", [])
        if "all" in perms or "lb_paquetes" in perms:
            # Usuario autorizado
            if self._on_success:
                self._on_success()
            self._close()
        else:
            self._lbl_error.configure(
                text="Este usuario no tiene permisos de configuracion.",
            )

    # ------------------------------------------------------------------
    # Cerrar
    # ------------------------------------------------------------------

    def _close(self):
        if self._on_cancel:
            self._on_cancel()
        self.place_forget()
        self.destroy()
