from __future__ import annotations

"""Fenêtre modale d’affichage et de gestion de la licence."""

import datetime as dt
import tkinter as tk
from pathlib import Path
from tkinter import filedialog, messagebox, ttk
from typing import Any, Callable, Dict, Optional

from .i18n import localization


class LicenseStatusDialog:
    """Dialogue modal présentant l’état de la licence et les options disponibles."""

    def __init__(
        self,
        parent: tk.Tk,
        status_provider: Callable[[], Dict[str, Any]],
        import_callback: Callable[[Path], bool],
    ):
        self.parent = parent
        self.status_provider = status_provider
        self.import_callback = import_callback

        self.window: Optional[tk.Toplevel] = None
        self.status: Dict[str, Any] = {}

        self.fields: Dict[str, ttk.Label] = {}
        self.feature_vars: Dict[str, tk.StringVar] = {}
        self.alert_var = tk.StringVar(value="")

    def show(self) -> None:
        """Afficher (ou rafraîchir) le dialogue."""
        if self.window and tk.Toplevel.winfo_exists(self.window):
            self._refresh()
            self.window.lift()
            return

        self.window = tk.Toplevel(self.parent)
        self.window.title(localization.t("license_modal_title"))
        self.window.resizable(False, False)
        self.window.transient(self.parent)
        self.window.grab_set()

        container = ttk.Frame(self.window, padding=20)
        container.grid(sticky="nsew")

        self._build_header(container)
        self._build_core(container)
        self._build_feature_section(container)
        self._build_actions(container)

        self._refresh()
        self._center_window()

    # --- Construction UI ---------------------------------------------

    def _build_header(self, parent: ttk.Frame) -> None:
        header = ttk.Frame(parent)
        header.grid(row=0, column=0, sticky="ew")
        header.columnconfigure(1, weight=1)

        icon_label = ttk.Label(header, text="🔐", font=("Arial", 28))
        icon_label.grid(row=0, column=0, padx=(0, 12))

        title_label = ttk.Label(
            header,
            text=localization.t("license_modal_heading"),
            font=("Arial", 16, "bold"),
        )
        title_label.grid(row=0, column=1, sticky="w")

        alert_label = ttk.Label(
            header,
            textvariable=self.alert_var,
            font=("Arial", 11, "bold"),
            foreground="#d97706",
        )
        alert_label.grid(row=1, column=0, columnspan=2, sticky="w", pady=(12, 0))

    def _build_core(self, parent: ttk.Frame) -> None:
        body = ttk.LabelFrame(parent, text=localization.t("license_modal_details"), padding=15)
        body.grid(row=1, column=0, sticky="ew", pady=(20, 12))

        fields = [
            ("license_modal_id", "license_id"),
            ("license_modal_tier", "tier"),
            ("license_modal_valid_until", "valid_until"),
            ("license_modal_expires_in", "expires_in_days"),
            ("license_modal_grace_hours", "grace_hours"),
            ("license_modal_max_domains", "max_domains"),
            ("license_modal_max_users", "max_users"),
        ]

        for row, (label_key, field_key) in enumerate(fields):
            ttk.Label(body, text=localization.t(label_key) + ":", width=22, anchor="w").grid(
                row=row, column=0, sticky="w", pady=2
            )
            value_label = ttk.Label(body, text="", anchor="w")
            value_label.grid(row=row, column=1, sticky="w", pady=2)
            self.fields[field_key] = value_label

    def _build_feature_section(self, parent: ttk.Frame) -> None:
        section = ttk.LabelFrame(parent, text=localization.t("license_modal_features"), padding=15)
        section.grid(row=2, column=0, sticky="ew")

        entries = [
            ("license_modal_feature_invasive", "invasive_tests"),
            ("license_modal_feature_html", "html_export"),
            ("license_modal_feature_multi_user", "multi_user"),
            ("license_modal_feature_api", "api_access"),
        ]

        for row, (label_key, feature_key) in enumerate(entries):
            label = ttk.Label(section, text="• " + localization.t(label_key))
            label.grid(row=row, column=0, sticky="w", pady=2)

            value_var = tk.StringVar(value="-")
            value_label = ttk.Label(section, textvariable=value_var, width=12, anchor="w")
            value_label.grid(row=row, column=1, sticky="w", padx=(12, 0))
            self.feature_vars[feature_key] = value_var

    def _build_actions(self, parent: ttk.Frame) -> None:
        actions = ttk.Frame(parent)
        actions.grid(row=3, column=0, sticky="ew", pady=(20, 0))
        actions.columnconfigure(0, weight=1)

        import_btn = ttk.Button(actions, text=localization.t("license_modal_import"), command=self._import_license)
        import_btn.grid(row=0, column=0, sticky="w")

        close_btn = ttk.Button(actions, text=localization.t("license_modal_close"), command=self._close)
        close_btn.grid(row=0, column=1, sticky="e")

    # --- Actions ------------------------------------------------------

    def _refresh(self) -> None:
        self.status = self.status_provider()
        self._update_fields()

    def _import_license(self) -> None:
        path_str = filedialog.askopenfilename(
            parent=self.window,
            title=localization.t("license_import_dialog_title"),
            filetypes=[("Licence Web Sentinel", "*.lic"), (localization.t("all_files"), "*.*")],
        )
        if not path_str:
            return

        try:
            success = self.import_callback(Path(path_str))
        except LicenceOperationError as exc:
            messagebox.showerror(localization.t("license_import_error_title"), str(exc), parent=self.window)
            return

        if success:
            messagebox.showinfo(localization.t("license_import_success_title"), localization.t("license_import_success"), parent=self.window)
            self._refresh()
        else:
            messagebox.showwarning(localization.t("license_import_warning_title"), localization.t("license_import_warning"), parent=self.window)

    def _close(self) -> None:
        if self.window:
            self.window.destroy()
            self.window = None

    # --- Helpers ------------------------------------------------------

    def _update_fields(self) -> None:
        status = self.status
        is_licensed = status.get("status") == "LICENSED"

        self.fields["license_id"].config(text=status.get("license_id") or localization.t("license_modal_unknown"))
        self.fields["tier"].config(text=status.get("tier", "FREE"))

        valid_until = status.get("valid_until")
        if valid_until:
            try:
                dt_value = dt.datetime.fromisoformat(valid_until.replace("Z", "+00:00"))
                date_text = dt_value.strftime("%Y-%m-%d %H:%M:%SZ")
            except ValueError:
                date_text = valid_until
        else:
            date_text = localization.t("license_modal_not_available")
        self.fields["valid_until"].config(text=date_text)

        expires_in = status.get("expires_in_days")
        if expires_in is None:
            expires_text = localization.t("license_modal_not_available")
        else:
            expires_text = localization.t("license_modal_days_value", max(0, expires_in))
        self.fields["expires_in_days"].config(text=expires_text)

        self.fields["grace_hours"].config(text=str(status.get("grace_hours", 0)))

        max_domains = status.get("max_domains")
        if max_domains is None or max_domains < 0:
            domains_text = localization.t("license_modal_unlimited")
        else:
            domains_text = str(max_domains)
        self.fields["max_domains"].config(text=domains_text)

        max_users = status.get("max_users")
        if max_users is None or max_users < 0:
            users_text = localization.t("license_modal_unlimited")
        else:
            users_text = str(max_users)
        self.fields["max_users"].config(text=users_text)

        features_enabled = status.get("features_enabled", {})
        for key, var in self.feature_vars.items():
            var.set(localization.t("license_modal_feature_enabled") if features_enabled.get(key, False) else localization.t("license_modal_feature_disabled"))

        alert_level = status.get("alert_level")
        threshold = status.get("alert_threshold")
        if status.get("status") != "LICENSED":
            self.alert_var.set("")
        elif alert_level == "CRITICAL":
            if threshold == 0 or status.get("valid") is False:
                self.alert_var.set(localization.t("license_alert_expired"))
            else:
                self.alert_var.set(localization.t("license_alert_critical", threshold))
        elif alert_level == "WARNING":
            self.alert_var.set(localization.t("license_alert_warning", threshold))
        elif alert_level == "INFO":
            self.alert_var.set(localization.t("license_alert_info", threshold))
        else:
            self.alert_var.set("")

        if not is_licensed and status.get("error"):
            self.alert_var.set(status["error"])

    def _center_window(self) -> None:
        if not self.window:
            return
        self.window.update_idletasks()
        width = self.window.winfo_width()
        height = self.window.winfo_height()
        x = (self.window.winfo_screenwidth() // 2) - (width // 2)
        y = (self.window.winfo_screenheight() // 2) - (height // 2)
        self.window.geometry(f"{width}x{height}+{x}+{y}")


class LicenceOperationError(RuntimeError):
    """Erreur utilisateur lors de l’import d’une licence."""


def show_license_status_dialog(
    parent: tk.Tk,
    status_provider: Callable[[], Dict[str, Any]],
    import_callback: Callable[[Path], bool],
) -> None:
    dialog = LicenseStatusDialog(parent, status_provider=status_provider, import_callback=import_callback)
    dialog.show()
