"""Provider capability registry.

Defines what events, template slots, commands, and variables each provider type supports.
Used by the frontend to dynamically show relevant UI elements.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


@dataclass
class ProviderCapabilities:
    """What a provider type supports."""

    provider_type: str
    display_name: str

    # Notification template slots (used in TemplateConfig)
    notification_slots: list[dict[str, str]] = field(default_factory=list)

    # Command template slots (used in CommandTemplateConfig)
    command_slots: list[dict[str, str]] = field(default_factory=list)

    # Events the provider can generate
    events: list[dict[str, str]] = field(default_factory=list)

    # Commands the provider supports
    commands: list[dict[str, str]] = field(default_factory=list)

    # Filter definitions for tracker UI (rendered dynamically by frontend)
    supported_filters: list[dict[str, str]] = field(default_factory=list)

    # Whether this provider receives webhooks (vs polling)
    webhook_based: bool = False

    # Action types this provider supports (used by Actions feature)
    action_types: list[dict[str, str]] = field(default_factory=list)


# ---------------------------------------------------------------------------
# Immich provider capabilities
# ---------------------------------------------------------------------------

IMMICH_CAPABILITIES = ProviderCapabilities(
    provider_type="immich",
    display_name="Immich",
    supported_filters=[
        {"key": "collections", "label": "Albums", "type": "select", "source": "api"},
    ],
    action_types=[
        {
            "key": "auto_organize",
            "name": "Auto-Organize",
            "description": "Sort assets into albums by person, search query, date, or favorites",
        },
    ],
    notification_slots=[
        {"name": "message_assets_added", "description": "New assets added to album"},
        {"name": "message_assets_removed", "description": "Assets removed from album"},
        {"name": "message_collection_renamed", "description": "Album renamed"},
        {"name": "message_collection_deleted", "description": "Album deleted"},
        {"name": "message_sharing_changed", "description": "Sharing status changed"},
        {"name": "periodic_summary_message", "description": "Periodic album summary"},
        {"name": "scheduled_assets_message", "description": "Scheduled asset delivery"},
        {"name": "memory_mode_message", "description": "On This Day memories"},
    ],
    command_slots=[
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status tracker summary"},
        {"name": "albums", "description": "/albums tracked albums list"},
        {"name": "events", "description": "/events recent events"},
        {"name": "people", "description": "/people detected people"},
        {"name": "search", "description": "/search results (also /find, /person, /place)"},
        {"name": "latest", "description": "/latest recent photos"},
        {"name": "favorites", "description": "/favorites starred items"},
        {"name": "random", "description": "/random random photos"},
        {"name": "summary", "description": "/summary album summary"},
        {"name": "memory", "description": "/memory On This Day photos"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_albums", "description": "Menu description for /albums"},
        {"name": "desc_events", "description": "Menu description for /events"},
        {"name": "usage_events", "description": "Usage example for /events"},
        {"name": "desc_summary", "description": "Menu description for /summary"},
        {"name": "desc_latest", "description": "Menu description for /latest"},
        {"name": "usage_latest", "description": "Usage example for /latest"},
        {"name": "desc_memory", "description": "Menu description for /memory"},
        {"name": "usage_memory", "description": "Usage example for /memory"},
        {"name": "desc_random", "description": "Menu description for /random"},
        {"name": "usage_random", "description": "Usage example for /random"},
        {"name": "desc_search", "description": "Menu description for /search"},
        {"name": "usage_search", "description": "Usage example for /search"},
        {"name": "desc_find", "description": "Menu description for /find"},
        {"name": "usage_find", "description": "Usage example for /find"},
        {"name": "desc_person", "description": "Menu description for /person"},
        {"name": "usage_person", "description": "Usage example for /person"},
        {"name": "desc_place", "description": "Menu description for /place"},
        {"name": "usage_place", "description": "Usage example for /place"},
        {"name": "desc_favorites", "description": "Menu description for /favorites"},
        {"name": "usage_favorites", "description": "Usage example for /favorites"},
        {"name": "desc_people", "description": "Menu description for /people"},
    ],
    events=[
        {"name": "assets_added", "description": "New assets detected in album"},
        {"name": "assets_removed", "description": "Assets removed from album"},
        {"name": "collection_renamed", "description": "Album was renamed"},
        {"name": "collection_deleted", "description": "Album was deleted"},
        {"name": "sharing_changed", "description": "Album sharing status changed"},
    ],
    commands=[
        {"name": "status", "description": "Show tracker status"},
        {"name": "albums", "description": "List tracked albums"},
        {"name": "events", "description": "Show recent events"},
        {"name": "summary", "description": "Send album summary"},
        {"name": "latest", "description": "Show latest photos"},
        {"name": "memory", "description": "On This Day memories"},
        {"name": "random", "description": "Random photos"},
        {"name": "search", "description": "Search assets"},
        {"name": "find", "description": "Find assets by name"},
        {"name": "person", "description": "Find photos by person"},
        {"name": "place", "description": "Find photos by location"},
        {"name": "favorites", "description": "Show favorites"},
        {"name": "people", "description": "List detected people"},
        {"name": "help", "description": "Show commands"},
    ],
)

# ---------------------------------------------------------------------------
# Gitea provider capabilities
# ---------------------------------------------------------------------------

GITEA_CAPABILITIES = ProviderCapabilities(
    provider_type="gitea",
    display_name="Gitea",
    webhook_based=True,
    supported_filters=[
        {
            "key": "collections",
            "label": "Repositories",
            "type": "tags",
            "placeholder": "owner/repo",
        },
        {
            "key": "senders",
            "label": "Only from users",
            "type": "tags",
            "placeholder": "username",
        },
        {
            "key": "exclude_senders",
            "label": "Exclude users",
            "type": "tags",
            "placeholder": "bot-name",
        },
    ],
    notification_slots=[
        {"name": "message_push", "description": "Code pushed to repository"},
        {"name": "message_issue_opened", "description": "Issue opened"},
        {"name": "message_issue_closed", "description": "Issue closed"},
        {"name": "message_issue_commented", "description": "Comment on issue"},
        {"name": "message_pr_opened", "description": "Pull request opened"},
        {"name": "message_pr_closed", "description": "Pull request closed"},
        {"name": "message_pr_merged", "description": "Pull request merged"},
        {"name": "message_pr_commented", "description": "Comment on pull request"},
        {"name": "message_release_published", "description": "Release published"},
    ],
    events=[
        {"name": "push", "description": "Code pushed to repository"},
        {"name": "issue_opened", "description": "Issue opened"},
        {"name": "issue_closed", "description": "Issue closed"},
        {"name": "issue_commented", "description": "Comment on issue"},
        {"name": "pr_opened", "description": "Pull request opened"},
        {"name": "pr_closed", "description": "Pull request closed"},
        {"name": "pr_merged", "description": "Pull request merged"},
        {"name": "pr_commented", "description": "Comment on pull request"},
        {"name": "release_published", "description": "Release published"},
    ],
    command_slots=[
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status tracker summary"},
        {"name": "repos", "description": "/repos tracked repositories"},
        {"name": "issues", "description": "/issues open issues"},
        {"name": "prs", "description": "/prs open pull requests"},
        {"name": "commits", "description": "/commits recent commits"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_repos", "description": "Menu description for /repos"},
        {"name": "desc_issues", "description": "Menu description for /issues"},
        {"name": "desc_prs", "description": "Menu description for /prs"},
        {"name": "desc_commits", "description": "Menu description for /commits"},
    ],
    commands=[
        {"name": "status", "description": "Show tracker status"},
        {"name": "repos", "description": "List tracked repositories"},
        {"name": "issues", "description": "Recent open issues"},
        {"name": "prs", "description": "Open pull requests"},
        {"name": "commits", "description": "Recent commits"},
        {"name": "help", "description": "Show commands"},
    ],
)

# ---------------------------------------------------------------------------
# Scheduler provider capabilities
# ---------------------------------------------------------------------------

SCHEDULER_CAPABILITIES = ProviderCapabilities(
    provider_type="scheduler",
    display_name="Scheduler",
    webhook_based=False,
    supported_filters=[],
    notification_slots=[
        {"name": "message_scheduled_message", "description": "Scheduled message"},
    ],
    command_slots=[],
    events=[
        {"name": "scheduled_message", "description": "Scheduled event fired"},
    ],
    commands=[],
)

# ---------------------------------------------------------------------------
# Planka provider capabilities
# ---------------------------------------------------------------------------

PLANKA_CAPABILITIES = ProviderCapabilities(
    provider_type="planka",
    display_name="Planka",
    webhook_based=True,
    supported_filters=[
        {
            "key": "collections",
            "label": "Boards",
            "type": "select",
            "source": "api",
        },
    ],
    notification_slots=[
        {"name": "message_card_created", "description": "Card created"},
        {"name": "message_card_updated", "description": "Card updated"},
        {"name": "message_card_moved", "description": "Card moved between lists"},
        {"name": "message_card_deleted", "description": "Card deleted"},
        {"name": "message_card_commented", "description": "Comment added to card"},
        {"name": "message_comment_updated", "description": "Comment updated"},
        {"name": "message_board_created", "description": "Board created"},
        {"name": "message_board_updated", "description": "Board updated"},
        {"name": "message_board_deleted", "description": "Board deleted"},
        {"name": "message_list_created", "description": "List created"},
        {"name": "message_list_updated", "description": "List updated"},
        {"name": "message_list_deleted", "description": "List deleted"},
        {"name": "message_attachment_created", "description": "Attachment added to card"},
        {"name": "message_card_label_added", "description": "Label added to card"},
        {"name": "message_task_completed", "description": "Task completed"},
    ],
    events=[
        {"name": "card_created", "description": "Card created"},
        {"name": "card_updated", "description": "Card updated"},
        {"name": "card_moved", "description": "Card moved between lists"},
        {"name": "card_deleted", "description": "Card deleted"},
        {"name": "card_commented", "description": "Comment added to card"},
        {"name": "comment_updated", "description": "Comment updated"},
        {"name": "board_created", "description": "Board created"},
        {"name": "board_updated", "description": "Board updated"},
        {"name": "board_deleted", "description": "Board deleted"},
        {"name": "list_created", "description": "List created"},
        {"name": "list_updated", "description": "List updated"},
        {"name": "list_deleted", "description": "List deleted"},
        {"name": "attachment_created", "description": "Attachment added"},
        {"name": "card_label_added", "description": "Label added to card"},
        {"name": "task_completed", "description": "Task completed"},
    ],
    command_slots=[
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status connection summary"},
        {"name": "boards", "description": "/boards tracked boards"},
        {"name": "cards", "description": "/cards recent cards"},
        {"name": "lists", "description": "/lists board lists"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_boards", "description": "Menu description for /boards"},
        {"name": "desc_cards", "description": "Menu description for /cards"},
        {"name": "desc_lists", "description": "Menu description for /lists"},
    ],
    commands=[
        {"name": "status", "description": "Show connection status"},
        {"name": "boards", "description": "List tracked boards"},
        {"name": "cards", "description": "Recent cards"},
        {"name": "lists", "description": "Board lists"},
        {"name": "help", "description": "Show commands"},
    ],
)

# ---------------------------------------------------------------------------
# NUT (Network UPS Tools) provider capabilities
# ---------------------------------------------------------------------------

NUT_CAPABILITIES = ProviderCapabilities(
    provider_type="nut",
    display_name="NUT (UPS)",
    webhook_based=False,
    supported_filters=[
        {"key": "collections", "label": "UPS Devices", "type": "select", "source": "api"},
    ],
    notification_slots=[
        {"name": "message_ups_online", "description": "UPS back on mains power"},
        {"name": "message_ups_on_battery", "description": "UPS switched to battery"},
        {"name": "message_ups_low_battery", "description": "Battery critically low"},
        {"name": "message_ups_battery_restored", "description": "Battery charge recovered"},
        {"name": "message_ups_comms_lost", "description": "Communication with UPS lost"},
        {"name": "message_ups_comms_restored", "description": "Communication with UPS restored"},
        {"name": "message_ups_replace_battery", "description": "Battery needs replacement"},
        {"name": "message_ups_overload", "description": "UPS load exceeded capacity"},
    ],
    events=[
        {"name": "ups_online", "description": "UPS back on mains power"},
        {"name": "ups_on_battery", "description": "UPS switched to battery"},
        {"name": "ups_low_battery", "description": "Battery critically low"},
        {"name": "ups_battery_restored", "description": "Battery charge recovered"},
        {"name": "ups_comms_lost", "description": "Communication lost"},
        {"name": "ups_comms_restored", "description": "Communication restored"},
        {"name": "ups_replace_battery", "description": "Battery needs replacement"},
        {"name": "ups_overload", "description": "UPS overloaded"},
    ],
    command_slots=[
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status UPS status summary"},
        {"name": "devices", "description": "/devices monitored UPS list"},
        {"name": "battery", "description": "/battery detailed battery report"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_devices", "description": "Menu description for /devices"},
        {"name": "desc_battery", "description": "Menu description for /battery"},
    ],
    commands=[
        {"name": "status", "description": "Show UPS status"},
        {"name": "devices", "description": "List monitored UPS devices"},
        {"name": "battery", "description": "Detailed battery report"},
        {"name": "help", "description": "Show commands"},
    ],
)

# ---------------------------------------------------------------------------
# Google Photos provider capabilities
# ---------------------------------------------------------------------------

GOOGLE_PHOTOS_CAPABILITIES = ProviderCapabilities(
    provider_type="google_photos",
    display_name="Google Photos",
    webhook_based=False,
    supported_filters=[
        {"key": "collections", "label": "Albums", "type": "select", "source": "api"},
    ],
    notification_slots=[
        {"name": "message_assets_added", "description": "New media added to album"},
        {"name": "message_assets_removed", "description": "Media removed from album"},
        {"name": "message_collection_renamed", "description": "Album renamed"},
        {"name": "message_collection_deleted", "description": "Album deleted"},
        {"name": "message_sharing_changed", "description": "Sharing status changed"},
    ],
    events=[
        {"name": "assets_added", "description": "New media detected in album"},
        {"name": "assets_removed", "description": "Media removed from album"},
        {"name": "collection_renamed", "description": "Album was renamed"},
        {"name": "collection_deleted", "description": "Album was deleted"},
        {"name": "sharing_changed", "description": "Album sharing status changed"},
    ],
    command_slots=[
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status tracker summary"},
        {"name": "albums", "description": "/albums tracked albums list"},
        {"name": "latest", "description": "/latest recent photos"},
        {"name": "search", "description": "/search by category or date"},
        {"name": "random", "description": "/random random photos"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_albums", "description": "Menu description for /albums"},
        {"name": "desc_latest", "description": "Menu description for /latest"},
        {"name": "usage_latest", "description": "Usage example for /latest"},
        {"name": "desc_search", "description": "Menu description for /search"},
        {"name": "usage_search", "description": "Usage example for /search"},
        {"name": "desc_random", "description": "Menu description for /random"},
        {"name": "usage_random", "description": "Usage example for /random"},
    ],
    commands=[
        {"name": "status", "description": "Show tracker status"},
        {"name": "albums", "description": "List tracked albums"},
        {"name": "latest", "description": "Show latest photos"},
        {"name": "search", "description": "Search media"},
        {"name": "random", "description": "Random photos"},
        {"name": "help", "description": "Show commands"},
    ],
)

# ---------------------------------------------------------------------------
# Generic Webhook provider capabilities
# ---------------------------------------------------------------------------

WEBHOOK_CAPABILITIES = ProviderCapabilities(
    provider_type="webhook",
    display_name="Generic Webhook",
    webhook_based=True,
    supported_filters=[
        {
            "key": "collections",
            "label": "Collections",
            "type": "tags",
            "placeholder": "value from collection_path",
        },
    ],
    notification_slots=[
        {"name": "message_webhook_received", "description": "Incoming webhook event"},
    ],
    events=[
        {"name": "webhook_received", "description": "Webhook payload received"},
    ],
    command_slots=[
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status webhook summary"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
    ],
    commands=[
        {"name": "status", "description": "Show webhook status"},
        {"name": "help", "description": "Show commands"},
    ],
)

# ---------------------------------------------------------------------------
# Home Assistant provider capabilities
# ---------------------------------------------------------------------------

HOME_ASSISTANT_CAPABILITIES = ProviderCapabilities(
    provider_type="home_assistant",
    display_name="Home Assistant",
    webhook_based=False,
    supported_filters=[
        {
            "key": "collections",
            "label": "Entities",
            "type": "tags",
            "placeholder": "light.kitchen",
        },
        {
            "key": "entity_glob",
            "label": "Entity glob",
            "type": "tags",
            "placeholder": "light.*",
        },
        {
            "key": "domain_allowlist",
            "label": "Domains",
            "type": "tags",
            "placeholder": "light, binary_sensor",
        },
    ],
    notification_slots=[
        {"name": "message_ha_state_changed", "description": "Entity state changed"},
        {"name": "message_ha_automation_triggered", "description": "Automation triggered"},
        {"name": "message_ha_service_called", "description": "HA service called"},
        {"name": "message_ha_event_fired", "description": "Other HA event fired"},
    ],
    events=[
        {"name": "ha_state_changed", "description": "Entity state changed"},
        {"name": "ha_automation_triggered", "description": "Automation triggered"},
        {"name": "ha_service_called", "description": "HA service called"},
        {"name": "ha_event_fired", "description": "Other HA event fired (catch-all)"},
    ],
    command_slots=[
        # Response templates
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status connection summary"},
        {"name": "entities", "description": "/entities matching glob"},
        {"name": "state", "description": "/state single-entity drill-down"},
        {"name": "areas", "description": "/areas with entity counts"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        # Description slots
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_entities", "description": "Menu description for /entities"},
        {"name": "desc_state", "description": "Menu description for /state"},
        {"name": "desc_areas", "description": "Menu description for /areas"},
        # Usage examples
        {"name": "usage_entities", "description": "Usage example for /entities"},
        {"name": "usage_state", "description": "Usage example for /state"},
    ],
    commands=[
        {"name": "status", "description": "Show connection status"},
        {"name": "entities", "description": "List entities (optional glob)"},
        {"name": "state", "description": "Show state for one entity"},
        {"name": "areas", "description": "List HA areas with entity counts"},
        {"name": "help", "description": "Show commands"},
    ],
)


# ---------------------------------------------------------------------------
# Bridge self-monitoring capabilities
# ---------------------------------------------------------------------------

BRIDGE_SELF_CAPABILITIES = ProviderCapabilities(
    provider_type="bridge_self",
    display_name="Bridge Self-Monitoring",
    webhook_based=False,
    supported_filters=[],
    notification_slots=[
        {
            "name": "message_bridge_self_poll_failures",
            "description": "Tracker poll failures crossed threshold",
        },
        {
            "name": "message_bridge_self_deferred_backlog",
            "description": "Deferred dispatch backlog crossed threshold",
        },
        {
            "name": "message_bridge_self_target_failures",
            "description": "Target send failures crossed threshold",
        },
    ],
    events=[
        {"name": "bridge_self_poll_failures", "description": "Tracker poll failures"},
        {"name": "bridge_self_deferred_backlog", "description": "Deferred backlog high"},
        {"name": "bridge_self_target_failures", "description": "Target send failures"},
    ],
    command_slots=[
        # Response templates
        {"name": "start", "description": "/start greeting message"},
        {"name": "help", "description": "/help command listing"},
        {"name": "status", "description": "/status full counter snapshot"},
        {"name": "thresholds", "description": "/thresholds configured alert thresholds"},
        {"name": "reset", "description": "/reset manual counter reset"},
        {"name": "health", "description": "/health terse one-line summary"},
        {"name": "rate_limited", "description": "Rate limit warning message"},
        {"name": "no_results", "description": "Empty results fallback"},
        # Description slots
        {"name": "desc_help", "description": "Menu description for /help"},
        {"name": "desc_status", "description": "Menu description for /status"},
        {"name": "desc_thresholds", "description": "Menu description for /thresholds"},
        {"name": "desc_reset", "description": "Menu description for /reset"},
        {"name": "desc_health", "description": "Menu description for /health"},
        # Usage examples
        {"name": "usage_reset", "description": "Usage example for /reset"},
    ],
    commands=[
        {"name": "status", "description": "Show current bridge health counters"},
        {"name": "thresholds", "description": "Show configured alert thresholds"},
        {"name": "reset", "description": "Manually reset a failure counter"},
        {"name": "health", "description": "Terse one-line health summary"},
        {"name": "help", "description": "Show commands"},
    ],
)


# ---------------------------------------------------------------------------
# Registry
# ---------------------------------------------------------------------------

_REGISTRY: dict[str, ProviderCapabilities] = {
    "immich": IMMICH_CAPABILITIES,
    "gitea": GITEA_CAPABILITIES,
    "planka": PLANKA_CAPABILITIES,
    "scheduler": SCHEDULER_CAPABILITIES,
    "nut": NUT_CAPABILITIES,
    "google_photos": GOOGLE_PHOTOS_CAPABILITIES,
    "webhook": WEBHOOK_CAPABILITIES,
    "home_assistant": HOME_ASSISTANT_CAPABILITIES,
    "bridge_self": BRIDGE_SELF_CAPABILITIES,
}


def get_capabilities(provider_type: str) -> ProviderCapabilities | None:
    """Get capabilities for a provider type."""
    return _REGISTRY.get(provider_type)


def get_all_capabilities() -> dict[str, ProviderCapabilities]:
    """Get all registered provider capabilities."""
    return dict(_REGISTRY)
