"""Command palette provider for Sibilance TUI.

Provides searchable commands: navigation, creature actions, info queries.
Uses progressive discovery — commands unlock based on creature state.
"""

from __future__ import annotations

from functools import partial
from typing import TYPE_CHECKING

from textual.command import Hit, Hits, Provider

if TYPE_CHECKING:
    from sibilance.app import SibilanceApp


class SibilanceCommands(Provider):
    """Core command palette entries for Sibilance."""

    async def search(self, query: str) -> Hits:
        """Yield matching commands for the given query."""
        app: SibilanceApp = self.screen.app  # type: ignore[assignment]
        matcher = self.matcher(query)
        creature = app.creature

        # Always-available commands
        commands: list[tuple[str, str, str]] = [
            ("Dashboard", "Go to the main dashboard", "dashboard"),
            ("World", "View world state, weather, and events", "world"),
            ("World status", "Quick world state summary", "_cmd_world"),
            ("Account", "View profile, subscription, and billing", "account"),
            ("Switch creature", "Switch between your creatures", "creatures"),
            ("Quit", "Exit Sibilance", "_cmd_quit"),
        ]

        # Creature-dependent commands — only show when a creature exists
        if creature is not None:
            commands.extend([
                ("Chat", "Open conversation with your creature", "conversation"),
                ("Journal", "Read your creature's journal", "journal"),
                ("Friends", "View creature relationships", "friends"),
                ("Den", "View dens and territories", "den"),
                ("Sleep", "View and adjust sleep schedule", "sleep"),
                ("Feed creature", "Feed your creature", "_cmd_feed"),
            ])

            # Higher bond / advanced commands
            bond_trust = creature.bond.trust if creature.bond else 0.0
            if bond_trust >= 0.2:
                commands.append(
                    ("Gift creature", "Give a gift", "_cmd_gift"),
                )
            if bond_trust >= 0.3:
                commands.append(
                    ("Guide creature", "Offer guidance", "_cmd_guide"),
                )

        for display, help_text, target in commands:
            score = matcher.match(display)
            if score > 0:
                # Screen names go through switch_screen, others are method calls
                if target.startswith("_cmd_"):
                    callback = getattr(app, target, None)
                    if callback is None:
                        continue
                else:
                    callback = partial(app.action_switch_screen, target)

                yield Hit(
                    score,
                    matcher.highlight(display),
                    callback,
                    help=help_text,
                )
