"""
Add Entry modal window for the hosts TUI application.

This module provides a floating modal window for creating new host entries.
"""

from textual.app import ComposeResult
from textual.containers import Vertical, VerticalScroll, Horizontal
from textual.widgets import Static, Button, Input, Checkbox, RadioSet, RadioButton
from textual.screen import ModalScreen
from textual.binding import Binding

from ..core.models import HostEntry
from .styles import ADD_ENTRY_MODAL_CSS


class AddEntryModal(ModalScreen):
    """
    Modal screen for adding new host entries.

    Provides a floating window with input fields for creating new entries.
    """

    CSS = ADD_ENTRY_MODAL_CSS

    BINDINGS = [
        Binding("escape", "cancel", "Cancel"),
        Binding("ctrl+s", "save", "Save"),
    ]

    def __init__(self):
        super().__init__()

    def compose(self) -> ComposeResult:
        """Create the add entry modal layout."""
        with VerticalScroll(classes="add-entry-container"):
            yield Static("Add New Host Entry", classes="add-entry-title")

            # Entry Type Selection
            with Vertical(classes="default-flex-section") as entry_type:
                entry_type.border_title = "Entry Type"
                with RadioSet(id="entry-type-radio", classes="default-radio-set"):
                    yield RadioButton("IP Address Entry", value=True, id="ip-entry-radio")
                    yield RadioButton("DNS Name Entry", id="dns-entry-radio")

            # IP Address Section
            with Vertical(classes="default-section", id="ip-section") as ip_address:
                ip_address.border_title = "IP Address"
                yield Input(
                    placeholder="e.g., 192.168.1.1 or 2001:db8::1",
                    id="ip-address-input",
                    classes="default-input",
                )
                yield Static("", id="ip-error", classes="validation-error")

            # DNS Name Section (initially hidden)
            with Vertical(classes="default-section hidden", id="dns-section") as dns_name:
                dns_name.border_title = "DNS Name (to resolve)"
                yield Input(
                    placeholder="e.g., example.com",
                    id="dns-name-input",
                    classes="default-input",
                )
                yield Static("", id="dns-error", classes="validation-error")

            # Hostnames Section
            with Vertical(classes="default-section") as hostnames:
                hostnames.border_title = "Hostnames"
                yield Input(
                    placeholder="e.g., example.com, www.example.com",
                    id="hostnames-input",
                    classes="default-input",
                )
                yield Static("", id="hostnames-error", classes="validation-error")

            # Comment Section
            with Vertical(classes="default-section") as comment:
                comment.border_title = "Comment (optional)"
                yield Input(
                    placeholder="e.g., Development server",
                    id="comment-input",
                    classes="default-input",
                )

            # Active Checkbox
            with Vertical(classes="default-section") as active:
                active.border_title = "Activate Entry"
                yield Checkbox(
                    "Active",
                    value=True,
                    id="active-checkbox",
                    classes="default-checkbox",
                )

            # Buttons
            with Horizontal(classes="button-row"):
                yield Button(
                    "Add Entry (CTRL+S)",
                    variant="primary",
                    id="add-button",
                    classes="default-button",
                )
                yield Button(
                    "Cancel (ESC)",
                    variant="default",
                    id="cancel-button",
                    classes="default-button",
                )

    def on_mount(self) -> None:
        """Focus IP address input when modal opens."""
        ip_input = self.query_one("#entry-type-radio", RadioSet)
        ip_input.focus()

    def on_radio_set_changed(self, event: RadioSet.Changed) -> None:
        """Handle entry type radio button changes."""
        if event.radio_set.id == "entry-type-radio":
            pressed_radio = event.pressed
            if pressed_radio and pressed_radio.id == "ip-entry-radio":
                # Show IP section, hide DNS section
                ip_section = self.query_one("#ip-section")
                dns_section = self.query_one("#dns-section") 
                active_checkbox = self.query_one("#active-checkbox", Checkbox)
                active_section = self.query_one("#active-checkbox").parent
                
                ip_section.remove_class("hidden")
                dns_section.add_class("hidden")
                
                # Reset checkbox to default (active) for IP entries
                active_checkbox.value = True
                active_section.border_title = "Activate Entry"
                
                # Focus IP input
                ip_input = self.query_one("#ip-address-input", Input)
                ip_input.focus()
            elif pressed_radio and pressed_radio.id == "dns-entry-radio":
                # Show DNS section, hide IP section
                ip_section = self.query_one("#ip-section")
                dns_section = self.query_one("#dns-section")
                active_checkbox = self.query_one("#active-checkbox", Checkbox)
                active_section = self.query_one("#active-checkbox").parent
                
                ip_section.add_class("hidden")
                dns_section.remove_class("hidden")
                
                # Set checkbox to inactive for DNS entries (will be activated after resolution)
                active_checkbox.value = False
                active_section.border_title = "Activate Entry (DNS entries activate after resolution)"
                
                # Focus DNS input
                dns_input = self.query_one("#dns-name-input", Input)
                dns_input.focus()

    def on_button_pressed(self, event: Button.Pressed) -> None:
        """Handle button presses."""
        if event.button.id == "add-button":
            self.action_save()
        elif event.button.id == "cancel-button":
            self.action_cancel()

    def action_save(self) -> None:
        """Validate and save new entry."""
        # Clear previous errors
        self._clear_errors()

        # Determine entry type
        radio_set = self.query_one("#entry-type-radio", RadioSet)
        is_dns_entry = radio_set.pressed_button and radio_set.pressed_button.id == "dns-entry-radio"

        # Get form values
        ip_address = self.query_one("#ip-address-input", Input).value.strip()
        dns_name = self.query_one("#dns-name-input", Input).value.strip()
        hostnames_str = self.query_one("#hostnames-input", Input).value.strip()
        comment = self.query_one("#comment-input", Input).value.strip()
        is_active = self.query_one("#active-checkbox", Checkbox).value

        # Validate input based on entry type
        if not self._validate_input(ip_address, dns_name, hostnames_str, is_dns_entry):
            return

        try:
            # Parse hostnames
            hostnames = [h.strip() for h in hostnames_str.split(",") if h.strip()]

            # Create new entry
            if is_dns_entry:
                # DNS entry - use 0.0.0.0 as placeholder IP and set as inactive
                new_entry = HostEntry(
                    ip_address="0.0.0.0",  # Placeholder IP until DNS resolution
                    hostnames=hostnames,
                    comment=comment if comment else None,
                    is_active=False,  # Inactive until DNS is resolved
                )
                # Add DNS name field
                new_entry.dns_name = dns_name
                
                # Add resolution status fields if they don't exist
                if not hasattr(new_entry, 'resolved_ip'):
                    new_entry.resolved_ip = None
                if not hasattr(new_entry, 'last_resolved'):
                    new_entry.last_resolved = None
                if not hasattr(new_entry, 'dns_resolution_status'):
                    from ..core.dns import DNSResolutionStatus
                    new_entry.dns_resolution_status = DNSResolutionStatus.NOT_RESOLVED
            else:
                # IP entry
                new_entry = HostEntry(
                    ip_address=ip_address,
                    hostnames=hostnames,
                    comment=comment if comment else None,
                    is_active=is_active,
                )

            # Close modal and return the new entry
            self.dismiss(new_entry)

        except ValueError as e:
            # Display validation error
            if "IP address" in str(e).lower():
                self._show_error("ip-error", str(e))
            elif "DNS name" in str(e).lower():
                self._show_error("dns-error", str(e))
            else:
                self._show_error("hostnames-error", str(e))

    def action_cancel(self) -> None:
        """Cancel entry creation and close modal."""
        self.dismiss(None)

    def _validate_input(self, ip_address: str, dns_name: str, hostnames_str: str, is_dns_entry: bool) -> bool:
        """
        Validate user input.

        Args:
            ip_address: IP address to validate (for IP entries)
            dns_name: DNS name to validate (for DNS entries)
            hostnames_str: Comma-separated hostnames to validate
            is_dns_entry: Whether this is a DNS entry or IP entry

        Returns:
            True if input is valid, False otherwise
        """
        valid = True

        # Validate IP address or DNS name based on entry type
        if is_dns_entry:
            if not dns_name:
                self._show_error("dns-error", "DNS name is required")
                valid = False
            else:
                # Basic DNS name validation
                if (
                    " " in dns_name
                    or not dns_name.replace(".", "").replace("-", "").isalnum()
                    or dns_name.startswith(".")
                    or dns_name.endswith(".")
                    or ".." in dns_name
                ):
                    self._show_error("dns-error", "Invalid DNS name format")
                    valid = False
        else:
            if not ip_address:
                self._show_error("ip-error", "IP address is required")
                valid = False

        # Validate hostnames
        if not hostnames_str:
            self._show_error("hostnames-error", "At least one hostname is required")
            valid = False
        else:
            hostnames = [h.strip() for h in hostnames_str.split(",") if h.strip()]
            if not hostnames:
                self._show_error("hostnames-error", "At least one hostname is required")
                valid = False
            else:
                # Basic hostname validation
                for hostname in hostnames:
                    if (
                        " " in hostname
                        or not hostname.replace(".", "")
                        .replace("-", "")
                        .replace("_", "")
                        .isalnum()
                    ):
                        self._show_error(
                            "hostnames-error", f"Invalid hostname format: {hostname}"
                        )
                        valid = False
                        break

        return valid

    def _show_error(self, error_id: str, message: str) -> None:
        """Show validation error message."""
        try:
            error_widget = self.query_one(f"#{error_id}", Static)
            error_widget.update(message)
        except Exception:
            pass

    def _clear_errors(self) -> None:
        """Clear all validation error messages."""
        for error_id in ["ip-error", "dns-error", "hostnames-error"]:
            try:
                error_widget = self.query_one(f"#{error_id}", Static)
                error_widget.update("")
            except Exception:
                pass
