"""Pattern library for Hephaestus."""

from __future__ import annotations

from typing import Dict, List


class PatternLibrary:
    """Comprehensive library of Anvil patterns for detection and validation."""

    def __init__(self):
        self._material_3_patterns = {
            "components": {
                "NavigationDrawerLayout": {
                    "description": "Material 3 navigation drawer layout",
                    "properties": ["nav_items", "temporary", "permanent"],
                    "events": ["show", "hide", "item_selected"],
                    "indicators": [
                        "@theme.navigation_drawer",
                        "NavigationDrawerLayout",
                    ],
                },
                "NavigationRailLayout": {
                    "description": "Material 3 navigation rail layout",
                    "properties": ["nav_items", "leading", "trailing"],
                    "events": ["show", "hide", "item_selected"],
                    "indicators": ["@theme.navigation_rail", "NavigationRailLayout"],
                },
                "TopAppBar": {
                    "description": "Material 3 top app bar",
                    "properties": ["title", "navigation_icon", "actions"],
                    "events": ["icon_click", "action_click"],
                    "indicators": ["@theme.top_app_bar", "TopAppBar"],
                },
                "FloatingActionButton": {
                    "description": "Material 3 floating action button",
                    "properties": ["icon", "onclick", "visible"],
                    "events": ["click"],
                    "indicators": [
                        "FloatingActionButton",
                        "role: floating-action-button",
                    ],
                },
                "Card": {
                    "description": "Material 3 card component",
                    "properties": ["title", "content", "actions"],
                    "events": ["action_click"],
                    "indicators": [
                        "role: outlined-card",
                        "role: filled-card",
                        "role: elevated-card",
                    ],
                },
                "Chip": {
                    "description": "Material 3 chip component",
                    "properties": ["text", "icon", "closable", "onclick"],
                    "events": ["click", "close"],
                    "indicators": ["Chip", "role: chip"],
                },
                "DataTable": {
                    "description": "Material 3 data table",
                    "properties": ["columns", "rows", "auto_header"],
                    "events": ["row_selected", "cell_edited", "sort"],
                    "indicators": ["DataTable", "role: data-table"],
                },
            },
            "roles": {
                "outlined-button": {
                    "description": "Material 3 outlined button style",
                    "components": ["Button"],
                    "properties": ["text", "icon", "onclick"],
                },
                "filled-button": {
                    "description": "Material 3 filled button style",
                    "components": ["Button"],
                    "properties": ["text", "icon", "onclick"],
                },
                "tonal-button": {
                    "description": "Material 3 tonal button style",
                    "components": ["Button"],
                    "properties": ["text", "icon", "onclick"],
                },
                "text-button": {
                    "description": "Material 3 text button style",
                    "components": ["Button"],
                    "properties": ["text", "onclick"],
                },
                "outlined-card": {
                    "description": "Material 3 outlined card style",
                    "components": ["Card", "ColumnPanel"],
                    "properties": ["border", "elevation"],
                },
                "filled-card": {
                    "description": "Material 3 filled card style",
                    "components": ["Card", "ColumnPanel"],
                    "properties": ["background_color", "elevation"],
                },
                "elevated-card": {
                    "description": "Material 3 elevated card style",
                    "components": ["Card", "ColumnPanel"],
                    "properties": ["elevation", "shadow"],
                },
                "outlined-text-field": {
                    "description": "Material 3 outlined text field",
                    "components": ["TextBox"],
                    "properties": ["placeholder", "text", "on_change"],
                },
                "filled-text-field": {
                    "description": "Material 3 filled text field",
                    "components": ["TextBox"],
                    "properties": ["placeholder", "text", "on_change"],
                },
            },
            "layouts": {
                "navigation-drawer": {
                    "description": "Navigation drawer layout pattern",
                    "components": ["NavigationDrawerLayout"],
                    "structure": "drawer + main_content",
                },
                "navigation-rail": {
                    "description": "Navigation rail layout pattern",
                    "components": ["NavigationRailLayout"],
                    "structure": "rail + main_content",
                },
                "top-app-bar": {
                    "description": "Top app bar layout pattern",
                    "components": ["TopAppBar"],
                    "structure": "app_bar + content",
                },
            },
        }

        self._classic_patterns = {
            "components": {
                "ColumnPanel": {
                    "description": "Classic column panel layout",
                    "properties": ["spacing", "padding", "align"],
                    "events": ["show", "hide"],
                    "indicators": ["ColumnPanel", "add_component", "clear"],
                },
                "FlowPanel": {
                    "description": "Classic flow panel layout",
                    "properties": ["spacing", "padding", "wrap"],
                    "events": ["show", "hide"],
                    "indicators": ["FlowPanel", "add_component", "clear"],
                },
                "GridPanel": {
                    "description": "Classic grid panel layout",
                    "properties": ["spacing", "padding", "columns"],
                    "events": ["show", "hide"],
                    "indicators": ["GridPanel", "add_component", "clear"],
                },
                "XYPanel": {
                    "description": "Classic XY panel layout",
                    "properties": [],
                    "events": ["show", "hide"],
                    "indicators": ["XYPanel", "add_component"],
                },
                "Button": {
                    "description": "Classic button component",
                    "properties": ["text", "onclick", "enabled"],
                    "events": ["click"],
                    "indicators": ["Button", "text", "enabled"],
                },
                "TextBox": {
                    "description": "Classic text box component",
                    "properties": ["text", "placeholder", "on_change"],
                    "events": ["change", "focus", "blur"],
                    "indicators": ["TextBox", "text", "placeholder"],
                },
                "Label": {
                    "description": "Classic label component",
                    "properties": ["text", "align"],
                    "events": [],
                    "indicators": ["Label", "text"],
                },
                "DataGrid": {
                    "description": "Classic data grid component",
                    "properties": ["columns", "rows", "auto_header"],
                    "events": ["row_selected", "cell_edited"],
                    "indicators": ["DataGrid", "columns", "rows"],
                },
            },
            "layouts": {
                "panel-based": {
                    "description": "Panel-based layout pattern",
                    "components": ["ColumnPanel", "FlowPanel", "GridPanel"],
                    "structure": "nested_panels",
                }
            },
        }

        self._reactive_patterns = {
            "decorators": {
                "@reactive_class": {
                    "description": "Reactive class decorator",
                    "usage": "Class-level reactive behavior",
                    "indicators": ["@reactive_class", "reactive_instance"],
                },
                "@render_effect": {
                    "description": "Render effect decorator",
                    "usage": "Automatic UI updates on data changes",
                    "indicators": ["@render_effect", "bind"],
                },
            },
            "functions": {
                "signal": {
                    "description": "Create reactive signal",
                    "usage": "State management for reactive data",
                    "indicators": ["signal(", "reactive_instance("],
                },
                "reactive_instance": {
                    "description": "Create reactive instance",
                    "usage": "Wrap objects in reactive behavior",
                    "indicators": ["reactiveInstance(", "reactive_instance("],
                },
                "bind": {
                    "description": "Bind property to reactive data",
                    "usage": "Automatic UI updates",
                    "indicators": ["bind(", "writeback: true"],
                },
            },
            "patterns": {
                "automatic_updates": {
                    "description": "Automatic UI updates on data changes",
                    "components": ["TextBox", "Label", "Button"],
                    "indicators": ["@render_effect", "bind("],
                },
                "state_management": {
                    "description": "Centralized state management",
                    "components": ["signal", "reactive_instance"],
                    "indicators": ["signal(", "store"],
                },
            },
        }

        self._routing_patterns = {
            "official": {
                "@anvil.routing.route": {
                    "description": "Official Anvil routing decorator",
                    "usage": "Route definition for navigation",
                    "indicators": [
                        "@anvil.routing.route",
                        "anvil.routing.set_url_hash",
                    ],
                },
                "routing_context": {
                    "description": "Official routing context",
                    "usage": "Data passing between routes",
                    "indicators": ["routing_context", "load_data"],
                },
            },
            "anvil_extras": {
                "@anvil_extras.routing.route": {
                    "description": "Anvil Extras routing decorator",
                    "usage": "Legacy routing system",
                    "indicators": [
                        "@anvil_extras.routing.route",
                        "anvil_extras.routing.set_url_hash",
                    ],
                }
            },
            "custom": {
                "url_hash": {
                    "description": "URL hash-based routing",
                    "usage": "Manual URL management",
                    "indicators": ["get_url_hash", "set_url_hash", "open_form"],
                }
            },
        }

        self._data_layer_patterns = {
            "model_classes": {
                "@anvil.server.model_class": {
                    "description": "Anvil model class decorator",
                    "usage": "Type-safe data models",
                    "indicators": ["@anvil.server.model_class", "field(", "Link("],
                },
                "field_types": {
                    "description": "Model field definitions",
                    "usage": "Typed model fields",
                    "indicators": ["field(String", "field(Boolean)", "field(Link("],
                },
            },
            "anvil_extras_orm": {
                "@anvil_extras.orm.model_class": {
                    "description": "Anvil Extras ORM decorator",
                    "usage": "Legacy ORM system",
                    "indicators": ["@anvil_extras.orm.model_class", "Model."],
                }
            },
            "raw_tables": {
                "app_tables": {
                    "description": "Direct data table access",
                    "usage": "Raw database operations",
                    "indicators": ["app_tables.", ".get(", ".add_row("],
                }
            },
        }

    def get_pattern(self, category: str, pattern_name: str) -> Dict[str, any] | None:
        """Get specific pattern definition."""
        category_map = {
            "material_3": self._material_3_patterns,
            "classic": self._classic_patterns,
            "reactive": self._reactive_patterns,
            "routing": self._routing_patterns,
            "data_layer": self._data_layer_patterns,
        }

        if category not in category_map:
            return None

        category_patterns = category_map[category]

        # Navigate nested structure to find pattern
        parts = pattern_name.split(".")
        current = category_patterns

        for part in parts:
            if isinstance(current, dict) and part in current:
                current = current[part]
            else:
                return None

        return current if isinstance(current, dict) else None

    def get_all_patterns(self, category: str) -> Dict[str, any]:
        """Get all patterns in a category."""
        category_map = {
            "material_3": self._material_3_patterns,
            "classic": self._classic_patterns,
            "reactive": self._reactive_patterns,
            "routing": self._routing_patterns,
            "data_layer": self._data_layer_patterns,
        }

        return category_map.get(category, {})

    def search_patterns(self, query: str) -> List[Dict[str, any]]:
        """Search for patterns matching query."""
        results = []
        query_lower = query.lower()

        all_categories = [
            ("material_3", self._material_3_patterns),
            ("classic", self._classic_patterns),
            ("reactive", self._reactive_patterns),
            ("routing", self._routing_patterns),
            ("data_layer", self._data_layer_patterns),
        ]

        for category_name, category_patterns in all_categories:
            matches = self._search_in_category(
                category_patterns, query_lower, category_name
            )
            results.extend(matches)

        return results

    def _search_in_category(
        self, category_patterns: Dict[str, any], query: str, category_name: str
    ) -> List[Dict[str, any]]:
        """Search for patterns within a category."""
        matches = []

        for pattern_name, pattern_def in category_patterns.items():
            if isinstance(pattern_def, dict):
                # Search in pattern name
                if query in pattern_name.lower():
                    matches.append(
                        {
                            "category": category_name,
                            "pattern": pattern_name,
                            "match_type": "name",
                            "definition": pattern_def,
                        }
                    )

                # Search in description
                description = pattern_def.get("description", "")
                if query in description.lower():
                    matches.append(
                        {
                            "category": category_name,
                            "pattern": pattern_name,
                            "match_type": "description",
                            "definition": pattern_def,
                        }
                    )

                # Search in indicators
                indicators = pattern_def.get("indicators", [])
                if isinstance(indicators, list):
                    for indicator in indicators:
                        if query in indicator.lower():
                            matches.append(
                                {
                                    "category": category_name,
                                    "pattern": pattern_name,
                                    "match_type": "indicator",
                                    "definition": pattern_def,
                                    "matched_indicator": indicator,
                                }
                            )

        return matches
