"""
Filter modal for advanced entry filtering configuration.

This module provides a professional modal dialog for configuring comprehensive
filtering options including status, type, resolution status, and search filtering.
"""

from textual.app import ComposeResult
from textual.containers import Grid, Horizontal, Container
from textual.widgets import (
    Static, Button, Checkbox, Input, Select, Label, 
    RadioSet, RadioButton, Collapsible
)
from textual.screen import ModalScreen
from textual.reactive import reactive
from textual import on
from typing import Optional, Dict, List

from ..core.filters import FilterOptions, EntryFilter


class FilterModal(ModalScreen[Optional[FilterOptions]]):
    """Advanced filtering configuration modal."""
    
    DEFAULT_CSS = """
    FilterModal {
        align: center middle;
    }
    
    #filter-dialog {
        grid-size: 1;
        grid-gutter: 1 2;
        grid-rows: auto 1fr auto;
        padding: 0 1;
        width: 80;
        height: auto;
        border: thick $background 80%;
        background: $surface;
        max-height: 90%;
    }
    
    #filter-header {
        dock: top;
        width: 1fr;
        height: 3;
        content-align: center middle;
        text-style: bold;
        background: $primary;
        color: $text;
    }
    
    #filter-content {
        layout: vertical;
        overflow-y: auto;
        height: auto;
        max-height: 70vh;
        padding: 1;
    }
    
    #filter-actions {
        dock: bottom;
        layout: horizontal;
        width: 1fr;
        height: 3;
        align: center middle;
        padding: 0 1;
        background: $panel;
    }
    
    .filter-section {
        margin: 1 0;
        padding: 1;
        border: round $primary 20%;
        background: $panel;
    }
    
    .filter-section-title {
        text-style: bold;
        color: $primary;
        margin-bottom: 1;
    }
    
    .filter-checkboxes {
        layout: vertical;
        margin: 0 2;
    }
    
    .filter-radios {
        layout: vertical;
        margin: 0 2;
    }
    
    .filter-input-row {
        layout: horizontal;
        margin: 0 2;
        height: 3;
        align: center left;
    }
    
    .filter-input-label {
        width: 20;
        content-align: left middle;
        margin-right: 1;
    }
    
    .filter-input {
        width: 30;
    }
    
    .preset-row {
        layout: horizontal;
        margin: 1 2;
        height: 3;
        align: center left;
    }
    
    .preset-select {
        width: 30;
        margin-right: 2;
    }
    
    Button {
        margin: 0 1;
        min-width: 12;
    }
    
    Checkbox {
        margin: 0 1;
    }
    
    RadioButton {
        margin: 0 1;
    }
    
    .count-display {
        text-style: italic;
        color: $text-muted;
        content-align: center middle;
        height: 1;
        margin: 1 0;
    }
    """
    
    # Reactive properties for real-time updates
    current_options: reactive[FilterOptions] = reactive(FilterOptions())
    entry_counts: reactive[Dict[str, int]] = reactive({})
    
    def __init__(self, initial_options: Optional[FilterOptions] = None, 
                 entries: Optional[List] = None, 
                 entry_filter: Optional[EntryFilter] = None):
        """
        Initialize filter modal.
        
        Args:
            initial_options: Current filter options to display
            entries: List of entries for count preview
            entry_filter: EntryFilter instance for applying filters
        """
        super().__init__()
        self.current_options = initial_options or FilterOptions()
        self.entries = entries or []
        self.entry_filter = entry_filter or EntryFilter()
        self.entry_counts = self._calculate_counts()
    
    def compose(self) -> ComposeResult:
        """Compose the filter modal interface."""
        with Grid(id="filter-dialog"):
            yield Static("Advanced Filtering", id="filter-header")
            
            with Container(id="filter-content"):
                # Filter presets section
                with Collapsible(title="Filter Presets", collapsed=False):
                    with Container(classes="filter-section"):
                        with Horizontal(classes="preset-row"):
                            yield Label("Preset:", classes="filter-input-label")
                            yield Select(
                                [(name, name) for name in self.entry_filter.get_preset_names()],
                                value=self.current_options.preset_name,
                                id="preset-select",
                                classes="preset-select"
                            )
                            yield Button("Load", id="load-preset", variant="primary")
                            yield Button("Save", id="save-preset")
                            yield Button("Delete", id="delete-preset", variant="error")
                
                # Status filtering section
                with Collapsible(title="Status Filtering", collapsed=False):
                    with Container(classes="filter-section"):
                        yield Static("Status Filtering", classes="filter-section-title")
                        with RadioSet(id="status-filter-type"):
                            yield RadioButton("Show All", value="all", id="status-all")
                            yield RadioButton("Active Only", value="active", id="status-active")
                            yield RadioButton("Inactive Only", value="inactive", id="status-inactive")
                            yield RadioButton("Custom", value="custom", id="status-custom")
                        
                        with Container(classes="filter-checkboxes", id="status-custom-options"):
                            yield Checkbox("Show Active Entries", value=True, id="show-active")
                            yield Checkbox("Show Inactive Entries", value=True, id="show-inactive")
                
                # DNS type filtering section
                with Collapsible(title="Entry Type Filtering", collapsed=False):
                    with Container(classes="filter-section"):
                        yield Static("Entry Type Filtering", classes="filter-section-title")
                        with RadioSet(id="type-filter-type"):
                            yield RadioButton("Show All", value="all", id="type-all")
                            yield RadioButton("DNS Entries Only", value="dns", id="type-dns")
                            yield RadioButton("IP Entries Only", value="ip", id="type-ip")
                            yield RadioButton("Custom", value="custom", id="type-custom")
                        
                        with Container(classes="filter-checkboxes", id="type-custom-options"):
                            yield Checkbox("Show DNS Entries", value=True, id="show-dns")
                            yield Checkbox("Show IP Entries", value=True, id="show-ip")
                
                # DNS resolution status filtering section
                with Collapsible(title="Resolution Status Filtering", collapsed=False):
                    with Container(classes="filter-section"):
                        yield Static("Resolution Status Filtering", classes="filter-section-title")
                        with RadioSet(id="resolution-filter-type"):
                            yield RadioButton("Show All", value="all", id="resolution-all")
                            yield RadioButton("Resolved Only", value="resolved", id="resolution-resolved")
                            yield RadioButton("Mismatches Only", value="mismatch", id="resolution-mismatch")
                            yield RadioButton("Custom", value="custom", id="resolution-custom")
                        
                        with Container(classes="filter-checkboxes", id="resolution-custom-options"):
                            yield Checkbox("Show Resolved", value=True, id="show-resolved")
                            yield Checkbox("Show Unresolved", value=True, id="show-unresolved")
                            yield Checkbox("Show Resolving", value=True, id="show-resolving")
                            yield Checkbox("Show Failed", value=True, id="show-failed")
                            yield Checkbox("Show Mismatched", value=True, id="show-mismatched")
                
                # Search filtering section
                with Collapsible(title="Search Filtering", collapsed=True):
                    with Container(classes="filter-section"):
                        yield Static("Search Filtering", classes="filter-section-title")
                        
                        with Horizontal(classes="filter-input-row"):
                            yield Label("Search term:", classes="filter-input-label")
                            yield Input(
                                placeholder="Enter search term...",
                                value=self.current_options.search_term or "",
                                id="search-term",
                                classes="filter-input"
                            )
                        
                        with Container(classes="filter-checkboxes"):
                            yield Checkbox("Search in hostnames", value=True, id="search-hostnames")
                            yield Checkbox("Search in comments", value=True, id="search-comments")
                            yield Checkbox("Search in IP addresses", value=True, id="search-ips")
                            yield Checkbox("Case sensitive", value=False, id="search-case-sensitive")
                
                # Entry count display
                yield Static("", id="count-display", classes="count-display")
            
            with Horizontal(id="filter-actions"):
                yield Button("Apply", id="apply", variant="primary")
                yield Button("Reset", id="reset")
                yield Button("Cancel", id="cancel")
    
    def on_mount(self) -> None:
        """Initialize the modal with current options."""
        self._update_ui_from_options()
        self._update_count_display()
    
    def _update_ui_from_options(self) -> None:
        """Update UI controls to reflect current options."""
        options = self.current_options
        
        # Status filtering
        if options.active_only:
            self.query_one("#status-active", RadioButton).value = True
        elif options.inactive_only:
            self.query_one("#status-inactive", RadioButton).value = True
        elif options.show_active and options.show_inactive:
            self.query_one("#status-all", RadioButton).value = True
        else:
            self.query_one("#status-custom", RadioButton).value = True
        
        self.query_one("#show-active", Checkbox).value = options.show_active
        self.query_one("#show-inactive", Checkbox).value = options.show_inactive
        
        # Type filtering
        if options.dns_only:
            self.query_one("#type-dns", RadioButton).value = True
        elif options.ip_only:
            self.query_one("#type-ip", RadioButton).value = True
        elif options.show_dns_entries and options.show_ip_entries:
            self.query_one("#type-all", RadioButton).value = True
        else:
            self.query_one("#type-custom", RadioButton).value = True
        
        self.query_one("#show-dns", Checkbox).value = options.show_dns_entries
        self.query_one("#show-ip", Checkbox).value = options.show_ip_entries
        
        # Resolution status filtering
        if options.resolved_only:
            self.query_one("#resolution-resolved", RadioButton).value = True
        elif options.mismatch_only:
            self.query_one("#resolution-mismatch", RadioButton).value = True
        elif (options.show_resolved and options.show_unresolved and 
              options.show_resolving and options.show_failed and options.show_mismatched):
            self.query_one("#resolution-all", RadioButton).value = True
        else:
            self.query_one("#resolution-custom", RadioButton).value = True
        
        self.query_one("#show-resolved", Checkbox).value = options.show_resolved
        self.query_one("#show-unresolved", Checkbox).value = options.show_unresolved
        self.query_one("#show-resolving", Checkbox).value = options.show_resolving
        self.query_one("#show-failed", Checkbox).value = options.show_failed
        self.query_one("#show-mismatched", Checkbox).value = options.show_mismatched
        
        # Search filtering
        if options.search_term:
            self.query_one("#search-term", Input).value = options.search_term
        self.query_one("#search-hostnames", Checkbox).value = options.search_in_hostnames
        self.query_one("#search-comments", Checkbox).value = options.search_in_comments
        self.query_one("#search-ips", Checkbox).value = options.search_in_ips
        self.query_one("#search-case-sensitive", Checkbox).value = options.case_sensitive
        
        self._update_custom_options_visibility()
    
    def _update_custom_options_visibility(self) -> None:
        """Show/hide custom option containers based on radio selections."""
        # Status custom options
        status_custom = self.query_one("#status-custom", RadioButton).value
        status_container = self.query_one("#status-custom-options")
        status_container.display = status_custom
        
        # Type custom options
        type_custom = self.query_one("#type-custom", RadioButton).value
        type_container = self.query_one("#type-custom-options")
        type_container.display = type_custom
        
        # Resolution custom options
        resolution_custom = self.query_one("#resolution-custom", RadioButton).value
        resolution_container = self.query_one("#resolution-custom-options")
        resolution_container.display = resolution_custom
    
    def _calculate_counts(self) -> Dict[str, int]:
        """Calculate entry counts for current filter options."""
        if not self.entries:
            return {}
        return self.entry_filter.count_filtered_entries(self.entries, self.current_options)
    
    def _update_count_display(self) -> None:
        """Update the count display with current filter results."""
        counts = self._calculate_counts()
        if counts:
            count_text = (
                f"Showing {counts['filtered']} of {counts['total']} entries "
                f"({counts['active']} active, {counts['inactive']} inactive)"
            )
        else:
            count_text = "No entries to filter"
        
        self.query_one("#count-display", Static).update(count_text)
    
    def _get_current_options_from_ui(self) -> FilterOptions:
        """Extract current filter options from UI controls."""
        # Status filtering
        status_type = self.query_one("#status-filter-type", RadioSet).pressed_button
        if status_type and status_type.id == "status-active":
            show_active, show_inactive = True, False
            active_only, inactive_only = True, False
        elif status_type and status_type.id == "status-inactive":
            show_active, show_inactive = False, True
            active_only, inactive_only = False, True
        elif status_type and status_type.id == "status-all":
            show_active, show_inactive = True, True
            active_only, inactive_only = False, False
        else:  # custom
            show_active = self.query_one("#show-active", Checkbox).value
            show_inactive = self.query_one("#show-inactive", Checkbox).value
            active_only, inactive_only = False, False
        
        # Type filtering
        type_type = self.query_one("#type-filter-type", RadioSet).pressed_button
        if type_type and type_type.id == "type-dns":
            show_dns_entries, show_ip_entries = True, False
            dns_only, ip_only = True, False
        elif type_type and type_type.id == "type-ip":
            show_dns_entries, show_ip_entries = False, True
            dns_only, ip_only = False, True
        elif type_type and type_type.id == "type-all":
            show_dns_entries, show_ip_entries = True, True
            dns_only, ip_only = False, False
        else:  # custom
            show_dns_entries = self.query_one("#show-dns", Checkbox).value
            show_ip_entries = self.query_one("#show-ip", Checkbox).value
            dns_only, ip_only = False, False
        
        # Resolution status filtering
        resolution_type = self.query_one("#resolution-filter-type", RadioSet).pressed_button
        if resolution_type and resolution_type.id == "resolution-resolved":
            resolved_only, mismatch_only = True, False
            show_resolved, show_unresolved, show_resolving, show_failed, show_mismatched = True, False, False, False, False
        elif resolution_type and resolution_type.id == "resolution-mismatch":
            resolved_only, mismatch_only = False, True
            show_resolved, show_unresolved, show_resolving, show_failed, show_mismatched = False, False, False, False, True
        elif resolution_type and resolution_type.id == "resolution-all":
            resolved_only, mismatch_only = False, False
            show_resolved, show_unresolved, show_resolving, show_failed, show_mismatched = True, True, True, True, True
        else:  # custom
            resolved_only, mismatch_only = False, False
            show_resolved = self.query_one("#show-resolved", Checkbox).value
            show_unresolved = self.query_one("#show-unresolved", Checkbox).value
            show_resolving = self.query_one("#show-resolving", Checkbox).value
            show_failed = self.query_one("#show-failed", Checkbox).value
            show_mismatched = self.query_one("#show-mismatched", Checkbox).value
        
        # Search filtering
        search_term = self.query_one("#search-term", Input).value or None
        search_hostnames = self.query_one("#search-hostnames", Checkbox).value
        search_comments = self.query_one("#search-comments", Checkbox).value
        search_ips = self.query_one("#search-ips", Checkbox).value
        case_sensitive = self.query_one("#search-case-sensitive", Checkbox).value
        
        return FilterOptions(
            show_active=show_active,
            show_inactive=show_inactive,
            active_only=active_only,
            inactive_only=inactive_only,
            show_dns_entries=show_dns_entries,
            show_ip_entries=show_ip_entries,
            dns_only=dns_only,
            ip_only=ip_only,
            show_resolved=show_resolved,
            show_unresolved=show_unresolved,
            show_resolving=show_resolving,
            show_failed=show_failed,
            show_mismatched=show_mismatched,
            mismatch_only=mismatch_only,
            resolved_only=resolved_only,
            search_term=search_term,
            search_in_hostnames=search_hostnames,
            search_in_comments=search_comments,
            search_in_ips=search_ips,
            case_sensitive=case_sensitive
        )
    
    @on(RadioSet.Changed)
    def on_radio_changed(self, event: RadioSet.Changed) -> None:
        """Handle radio button changes."""
        self._update_custom_options_visibility()
        self.current_options = self._get_current_options_from_ui()
        self._update_count_display()
    
    @on(Checkbox.Changed)
    @on(Input.Changed)
    def on_input_changed(self) -> None:
        """Handle input changes for real-time preview."""
        self.current_options = self._get_current_options_from_ui()
        self._update_count_display()
    
    @on(Button.Pressed, "#apply")
    def on_apply_pressed(self) -> None:
        """Handle apply button press."""
        self.dismiss(self._get_current_options_from_ui())
    
    @on(Button.Pressed, "#cancel")
    def on_cancel_pressed(self) -> None:
        """Handle cancel button press."""
        self.dismiss(None)
    
    @on(Button.Pressed, "#reset")
    def on_reset_pressed(self) -> None:
        """Handle reset button press."""
        self.current_options = FilterOptions()
        self._update_ui_from_options()
        self._update_count_display()
    
    @on(Button.Pressed, "#load-preset")
    def on_load_preset_pressed(self) -> None:
        """Handle load preset button press."""
        preset_select = self.query_one("#preset-select", Select)
        if preset_select.value != Select.BLANK:
            preset_options = self.entry_filter.load_preset(str(preset_select.value))
            if preset_options:
                self.current_options = preset_options
                self._update_ui_from_options()
                self._update_count_display()
    
    @on(Button.Pressed, "#save-preset")
    def on_save_preset_pressed(self) -> None:
        """Handle save preset button press."""
        # TODO: Implement preset name input dialog
        # For now, just save with a generic name
        current_options = self._get_current_options_from_ui()
        preset_name = f"Custom Preset {len(self.entry_filter.presets) + 1}"
        self.entry_filter.save_preset(preset_name, current_options)
        
        # Update preset select with new preset
        preset_select = self.query_one("#preset-select", Select)
        preset_select.set_options([(name, name) for name in self.entry_filter.get_preset_names()])
        preset_select.value = preset_name
    
    @on(Button.Pressed, "#delete-preset")
    def on_delete_preset_pressed(self) -> None:
        """Handle delete preset button press."""
        preset_select = self.query_one("#preset-select", Select)
        if preset_select.value != Select.BLANK:
            preset_name = str(preset_select.value)
            if self.entry_filter.delete_preset(preset_name):
                # Update preset select options
                preset_select.set_options([(name, name) for name in self.entry_filter.get_preset_names()])
                preset_select.value = Select.BLANK
