"""Mini-App registry for plugin-provided interactive chat components."""

from __future__ import annotations

import logging
from typing import Any, Callable, Awaitable

from pydantic import BaseModel, Field

logger = logging.getLogger(__name__)


class MiniAppDef(BaseModel):
    """Definition of a mini-app that plugins can register."""

    app_id: str = Field(..., description="Unique app identifier")
    name: str = Field(..., description="Display name")
    icon: str = Field(default="app", description="Icon name")
    description: str = Field(default="", description="App description")
    plugin_name: str = Field(..., description="Plugin that registered this app")
    render_schema: dict[str, Any] = Field(
        default_factory=dict, description="JSON schema for frontend rendering"
    )


class MiniAppRegistry:
    """Registry for mini-apps that plugins provide for chat embedding."""

    def __init__(self) -> None:
        self._apps: dict[str, MiniAppDef] = {}

    def register(
        self,
        app_id: str,
        name: str,
        icon: str,
        description: str,
        plugin_name: str,
        render_schema: dict[str, Any] | None = None,
    ) -> None:
        """Register a mini-app."""
        app = MiniAppDef(
            app_id=app_id,
            name=name,
            icon=icon,
            description=description,
            plugin_name=plugin_name,
            render_schema=render_schema or {},
        )
        self._apps[app_id] = app
        logger.info(f"Mini-app registered: {app_id} by {plugin_name}")

    def unregister(self, app_id: str) -> None:
        """Unregister a mini-app."""
        app = self._apps.pop(app_id, None)
        if app:
            logger.info(f"Mini-app unregistered: {app_id}")

    def unregister_plugin(self, plugin_name: str) -> None:
        """Unregister all mini-apps from a specific plugin."""
        to_remove = [app_id for app_id, app in self._apps.items() if app.plugin_name == plugin_name]
        for app_id in to_remove:
            self._apps.pop(app_id, None)
        if to_remove:
            logger.info(f"Unregistered {len(to_remove)} mini-apps from plugin {plugin_name}")

    def list_apps(self) -> list[dict[str, Any]]:
        """List all available mini-apps for frontend."""
        return [app.model_dump() for app in self._apps.values()]

    def get_app(self, app_id: str) -> MiniAppDef | None:
        """Get a specific mini-app definition."""
        return self._apps.get(app_id)
