"""
B2C Domain GUI Integration
==========================
GUI modifications to add B2C filtering controls to the fuzzy matcher application.
"""

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import logging
from pathlib import Path
from typing import Dict, Any

log = logging.getLogger(__name__)


class B2CFilterSettingsDialog(tk.Toplevel):
    """Dialog for managing B2C domain filter settings."""

    def __init__(self, parent, current_config: Dict[str, Any]):
        super().__init__(parent)

        self.title("Personal Domain Filter Settings")
        self.geometry("600x500")
        self.transient(parent)

        # Store config
        self.config = current_config.copy()
        self.result = None

        # Build UI
        self._build_ui()

        # Center on parent
        self.update_idletasks()
        x = parent.winfo_x() + (parent.winfo_width() // 2) - (self.winfo_width() // 2)
        y = parent.winfo_y() + (parent.winfo_height() // 2) - (self.winfo_height() // 2)
        self.geometry(f"+{x}+{y}")

        # Modal
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self._on_cancel)

    def _build_ui(self):
        """Build the settings dialog UI."""
        # Main container
        main_frame = ttk.Frame(self, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # Title and description
        title_label = ttk.Label(
            main_frame,
            text="Personal Domain List Settings",
            font=("TkDefaultFont", 12, "bold"),
        )
        title_label.pack(anchor="w", pady=(0, 5))

        desc_label = ttk.Label(
            main_frame,
            text="Configure how personal email domains (gmail.com, yahoo.com, etc.) "
            "are handled during matching.",
            wraplength=550,
        )
        desc_label.pack(anchor="w", pady=(0, 15))

        # Current status frame
        status_frame = ttk.LabelFrame(main_frame, text="Current Status", padding=10)
        status_frame.pack(fill="x", pady=(0, 15))

        # Get current domain list info
        domain_info = self._get_domain_list_info()

        status_text = f"Version: {domain_info['version']}\n"
        status_text += f"Domains: {domain_info['count']:,}\n"
        status_text += f"SHA256: {domain_info['sha256'][:16]}...\n"
        status_text += f"Memory: ~{domain_info['memory_kb']:.1f} KB"

        self.status_label = ttk.Label(status_frame, text=status_text)
        self.status_label.pack(anchor="w")

        # Settings frame
        settings_frame = ttk.LabelFrame(main_frame, text="Filter Settings", padding=10)
        settings_frame.pack(fill="both", expand=True, pady=(0, 15))

        # Enable/disable checkbox
        self.enabled_var = tk.BooleanVar(value=self.config.get("enabled", True))
        enabled_check = ttk.Checkbutton(
            settings_frame,
            text="Enable personal domain filtering",
            variable=self.enabled_var,
            command=self._on_enabled_toggle,
        )
        enabled_check.pack(anchor="w", pady=(0, 10))

        # Options frame
        self.options_frame = ttk.Frame(settings_frame)
        self.options_frame.pack(fill="both", expand=True, padx=(20, 0))

        # Extract from email option
        self.extract_email_var = tk.BooleanVar(
            value=self.config.get("extract_from_email", True)
        )
        extract_check = ttk.Checkbutton(
            self.options_frame,
            text="Extract domains from email addresses",
            variable=self.extract_email_var,
        )
        extract_check.pack(anchor="w", pady=2)

        # Company fallback option
        self.fallback_var = tk.BooleanVar(
            value=self.config.get("company_fallback", True)
        )
        fallback_check = ttk.Checkbutton(
            self.options_frame,
            text="Use company name for blocking when domain is filtered",
            variable=self.fallback_var,
        )
        fallback_check.pack(anchor="w", pady=2)

        # Stats tracking option
        self.stats_var = tk.BooleanVar(value=self.config.get("track_stats", True))
        stats_check = ttk.Checkbutton(
            self.options_frame,
            text="Track filtering statistics",
            variable=self.stats_var,
        )
        stats_check.pack(anchor="w", pady=2)

        # Domain list management
        ttk.Separator(self.options_frame, orient="horizontal").pack(
            fill="x", pady=(15, 10)
        )

        list_frame = ttk.Frame(self.options_frame)
        list_frame.pack(fill="x")

        ttk.Button(
            list_frame, text="Import Domain List...", command=self._import_domains
        ).pack(side="left", padx=(0, 5))

        ttk.Button(
            list_frame, text="Export Current List...", command=self._export_domains
        ).pack(side="left", padx=5)

        ttk.Button(
            list_frame, text="Reset to Default", command=self._reset_domains
        ).pack(side="left", padx=5)

        # Sample domains viewer
        sample_frame = ttk.LabelFrame(
            self.options_frame, text="Sample Domains (first 50)", padding=5
        )
        sample_frame.pack(fill="both", expand=True, pady=(15, 0))

        # Text widget with scrollbar
        text_frame = ttk.Frame(sample_frame)
        text_frame.pack(fill="both", expand=True)

        self.sample_text = tk.Text(
            text_frame, height=8, width=50, wrap="word", state="disabled"
        )
        self.sample_text.pack(side="left", fill="both", expand=True)

        scrollbar = ttk.Scrollbar(
            text_frame, orient="vertical", command=self.sample_text.yview
        )
        scrollbar.pack(side="right", fill="y")
        self.sample_text.configure(yscrollcommand=scrollbar.set)

        # Load sample domains
        self._load_sample_domains()

        # Update options state
        self._on_enabled_toggle()

        # Button bar
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill="x", pady=(15, 0))

        ttk.Button(
            button_frame, text="OK", command=self._on_ok, style="Primary.TButton"
        ).pack(side="right", padx=(5, 0))

        ttk.Button(button_frame, text="Cancel", command=self._on_cancel).pack(
            side="right"
        )

    def _get_domain_list_info(self) -> Dict[str, Any]:
        """Get information about current domain list."""
        # This would connect to the actual B2C checker
        # For now, return mock data
        return {
            "version": "20241215",
            "count": 12847,
            "sha256": "a1b2c3d4e5f6789012345678",
            "memory_kb": 812.5,
        }

    def _load_sample_domains(self):
        """Load sample domains into the text widget."""
        # This would load from the actual domain list
        # For now, show examples
        sample_domains = [
            "gmail.com",
            "yahoo.com",
            "hotmail.com",
            "outlook.com",
            "aol.com",
            "icloud.com",
            "protonmail.com",
            "mail.com",
            "yandex.com",
            "qq.com",
            "163.com",
            "comcast.net",
            "verizon.net",
            "att.net",
            "cox.net",
            "btinternet.com",
        ]

        self.sample_text.configure(state="normal")
        self.sample_text.delete("1.0", tk.END)

        for domain in sorted(sample_domains):
            self.sample_text.insert(tk.END, f"{domain}\n")

        self.sample_text.configure(state="disabled")

    def _on_enabled_toggle(self):
        """Handle enable/disable toggle."""
        enabled = self.enabled_var.get()
        state = "normal" if enabled else "disabled"

        # Update all child widgets
        for widget in self.options_frame.winfo_children():
            if isinstance(widget, (ttk.Checkbutton, ttk.Button)):
                widget.configure(state=state)
            elif isinstance(widget, ttk.Frame):
                for child in widget.winfo_children():
                    if isinstance(child, ttk.Button):
                        child.configure(state=state)

    def _import_domains(self):
        """Import a custom domain list."""
        file_path = filedialog.askopenfilename(
            title="Import Domain List",
            filetypes=[("Text files", "*.txt"), ("All files", "*.*")],
        )

        if file_path:
            try:
                # Here you would actually import the domains
                messagebox.showinfo(
                    "Import Successful",
                    f"Imported domains from:\n{Path(file_path).name}",
                )
                self._load_sample_domains()
            except Exception as e:
                messagebox.showerror(
                    "Import Error", f"Failed to import domains:\n{str(e)}"
                )

    def _export_domains(self):
        """Export current domain list."""
        file_path = filedialog.asksaveasfilename(
            title="Export Domain List",
            defaultextension=".txt",
            filetypes=[("Text files", "*.txt"), ("All files", "*.*")],
        )

        if file_path:
            try:
                # Here you would actually export the domains
                messagebox.showinfo(
                    "Export Successful", f"Exported domains to:\n{Path(file_path).name}"
                )
            except Exception as e:
                messagebox.showerror(
                    "Export Error", f"Failed to export domains:\n{str(e)}"
                )

    def _reset_domains(self):
        """Reset to default domain list."""
        if messagebox.askyesno(
            "Reset Domain List",
            "Reset to the default personal domain list?\n\n"
            "This will discard any custom domains you've added.",
        ):
            # Here you would reset to defaults
            self._load_sample_domains()
            messagebox.showinfo(
                "Reset Complete", "Domain list has been reset to defaults."
            )

    def _on_ok(self):
        """Save settings and close."""
        self.result = {
            "enabled": self.enabled_var.get(),
            "extract_from_email": self.extract_email_var.get(),
            "company_fallback": self.fallback_var.get(),
            "track_stats": self.stats_var.get(),
        }
        self.destroy()

    def _on_cancel(self):
        """Cancel without saving."""
        self.result = None
        self.destroy()


def add_b2c_filter_controls(parent_frame: ttk.Frame, app) -> ttk.Frame:
    """
    Add B2C filter controls to the preprocessing tab.

    Args:
        parent_frame: Parent frame (preprocessing tab)
        app: Main application instance

    Returns:
        Frame containing the controls
    """
    # Create B2C filter frame
    b2c_frame = ttk.LabelFrame(parent_frame, text=" Personal Email Domain Filtering ")
    b2c_frame.grid(row=1, column=0, sticky="ew", padx=5, pady=(10, 5))

    # Main checkbox
    app.b2c_enabled_var = tk.BooleanVar(value=True)

    main_check = ttk.Checkbutton(
        b2c_frame,
        text="Exclude personal email domains (B2C)",
        variable=app.b2c_enabled_var,
    )
    main_check.pack(anchor="w", padx=10, pady=(10, 5))

    # Info label
    info_label = ttk.Label(
        b2c_frame,
        text="When enabled, domains like gmail.com, yahoo.com are treated as blank "
        "to improve blocking precision.",
        wraplength=500,
        foreground="gray",
    )
    info_label.pack(anchor="w", padx=(30, 10), pady=(0, 5))

    # Settings button
    settings_btn = ttk.Button(
        b2c_frame, text="Settings...", command=lambda: _show_b2c_settings(app)
    )
    settings_btn.pack(anchor="w", padx=(30, 10), pady=(5, 10))

    # Create tooltip
    # from gui import ToolTip  # Import from main GUI module
    # ToolTip(
    #    main_check,
    #    "Enable this to filter out personal email domains during matching. "
    #    "This significantly improves match quality for B2B data."
    # )

    return b2c_frame


def _show_b2c_settings(app):
    """Show B2C filter settings dialog."""
    # Get current config
    current_config = getattr(
        app,
        "b2c_filter_config",
        {
            "enabled": True,
            "extract_from_email": True,
            "company_fallback": True,
            "track_stats": True,
        },
    )

    # Show dialog
    dialog = B2CFilterSettingsDialog(app, current_config)
    app.wait_window(dialog)

    # Apply results
    if dialog.result:
        app.b2c_filter_config = dialog.result
        app.b2c_enabled_var.set(dialog.result["enabled"])
        log.info(f"B2C filter settings updated: {dialog.result}")


def add_b2c_wizard_hint(app, mappings: list, source_df, ref_df=None):
    """
    Check if B2C filtering should be suggested and show hint.

    This should be called after mappings are confirmed.
    """
    # Check if any mapped columns contain high percentage of B2C domains
    from fmatch.core.b2c_bloom_filter import is_b2c_domain

    b2c_percentage_threshold = 0.25  # 25% B2C domains triggers suggestion

    for mapping in mappings:
        src_col = mapping.get("source")
        if not src_col or src_col not in source_df.columns:
            continue

        # Sample the column
        sample = source_df[src_col].dropna().head(1000)
        if sample.empty:
            continue

        # Check for domain-like content
        if any(kw in src_col.lower() for kw in ["domain", "email", "website"]):
            # Count B2C domains
            b2c_count = 0
            total_checked = 0

            for value in sample:
                value_str = str(value).lower().strip()

                # Try to extract domain
                if "@" in value_str:
                    parts = value_str.split("@")
                    if len(parts) == 2:
                        domain = parts[1]
                        if is_b2c_domain(domain):
                            b2c_count += 1
                        total_checked += 1
                elif "." in value_str and " " not in value_str:
                    # Might be a domain
                    if is_b2c_domain(value_str):
                        b2c_count += 1
                    total_checked += 1

            if total_checked > 0:
                b2c_ratio = b2c_count / total_checked

                if b2c_ratio >= b2c_percentage_threshold:
                    # Show suggestion
                    if not getattr(app, "b2c_enabled_var", tk.BooleanVar()).get():
                        response = messagebox.askyesno(
                            "Enable Personal Domain Filtering?",
                            f"Column '{src_col}' contains {b2c_ratio:.0%} personal email domains.\n\n"
                            "Enabling B2C domain filtering can significantly improve matching accuracy.\n\n"
                            "Would you like to enable it now?",
                            icon="info",
                        )

                        if response:
                            app.b2c_enabled_var.set(True)
                            log.info(
                                f"B2C filtering enabled based on wizard suggestion "
                                f"({src_col}: {b2c_ratio:.0%} B2C)"
                            )
                    break


# Integration with existing GUI preprocessing tab
def modify_preprocessing_tab(build_preprocessing_tab_method):
    """
    Decorator to modify the existing preprocessing tab builder.

    Usage:
        @modify_preprocessing_tab
        def _build_preprocessing_tab(self, parent):
            # Original implementation
    """

    def wrapper(self, parent):
        # Call original method
        build_preprocessing_tab_method(self, parent)

        # Add B2C controls
        add_b2c_filter_controls(parent, self)

    return wrapper


# Example of how to integrate into existing config save/load
def save_b2c_config(session_data: dict, app) -> dict:
    """Add B2C configuration to session data."""
    if hasattr(app, "b2c_filter_config"):
        session_data["b2c_filter"] = app.b2c_filter_config
    elif hasattr(app, "b2c_enabled_var"):
        session_data["b2c_filter"] = {"enabled": app.b2c_enabled_var.get()}
    return session_data


def load_b2c_config(session_data: dict, app):
    """Load B2C configuration from session data."""
    if "b2c_filter" in session_data:
        app.b2c_filter_config = session_data["b2c_filter"]
        if hasattr(app, "b2c_enabled_var"):
            app.b2c_enabled_var.set(session_data["b2c_filter"].get("enabled", True))
