"""
Secrets status and info providers.

Migrated from the flat providers.py to the providers/ package.
"""

import logging
from typing import Optional, Dict

from elizaos.runtime import AgentRuntime
from elizaos.types import Provider, Message

from ..types import SecretLevel, SecretContext


logger = logging.getLogger(__name__)


class SecretsStatusProvider(Provider):
    """Provides secrets configuration status to the LLM context."""

    name = "SECRETS_STATUS"
    description = "Provides information about configured secrets and their status"

    async def get(self, runtime: AgentRuntime, message: Message, state: Dict) -> Optional[str]:
        from ..service import SecretsService
        from ..activator import PluginActivatorService

        secrets_service: Optional[SecretsService] = runtime.get_service(SecretsService.service_type)
        if not secrets_service:
            return None

        context = SecretContext(level=SecretLevel.GLOBAL, agent_id=runtime.agent_id)
        metadata = await secrets_service.list(context)

        if not metadata:
            return "[Secrets Status]\nNo secrets are currently configured."

        keys_list = list(metadata.keys())
        valid = []
        missing = []
        invalid = []

        for key, config in metadata.items():
            status = getattr(config, "status", None)
            status_val = status.value if hasattr(status, "value") else str(status)
            if status_val in ("valid", "set"):
                valid.append(key)
            elif status_val == "missing":
                missing.append(key)
            elif status_val in ("invalid", "expired", "revoked"):
                invalid.append(key)
            else:
                valid.append(key)

        lines = ["[Secrets Status]"]
        if valid:
            lines.append(f"Configured secrets: {', '.join(valid)}")
        if invalid:
            lines.append(f"Invalid/expired secrets: {', '.join(invalid)}")
        if missing:
            lines.append(f"Missing required secrets: {', '.join(missing)}")

        # Check pending plugins
        activator: Optional[PluginActivatorService] = runtime.get_service(
            PluginActivatorService.service_type
        )
        if activator:
            pending = activator.get_pending_plugins()
            if pending:
                plugin_names = []
                for p in pending[:5]:
                    name = getattr(p.plugin.plugin, "name", "Unknown") if hasattr(p.plugin, "plugin") else "Unknown"
                    plugin_names.append(name)
                lines.append(f"Plugins waiting for secrets: {', '.join(plugin_names)}")

        return "\n".join(lines)


class SecretsInfoProvider(Provider):
    """Provides detailed secrets information when asked about secrets."""

    name = "SECRETS_INFO"
    description = "Provides detailed information about the secrets system"

    async def get(self, runtime: AgentRuntime, message: Message, state: Dict) -> Optional[str]:
        text = ""
        if isinstance(message.content, dict):
            text = message.content.get("text", "").lower()
        else:
            text = str(message.content).lower()

        if not any(kw in text for kw in ["secret", "api key", "token", "credential", "configure"]):
            return None

        from ..service import SecretsService

        secrets_service: Optional[SecretsService] = runtime.get_service(SecretsService.service_type)
        if not secrets_service:
            return "[Secrets Info]\nSecrets management is not available."

        context = SecretContext(level=SecretLevel.GLOBAL, agent_id=runtime.agent_id)
        metadata = await secrets_service.list(context)
        secret_count = len(metadata)

        if secret_count == 0:
            return (
                "[Secrets Info]\n"
                "No secrets configured. User can set secrets by saying things like "
                '"Set my OPENAI_API_KEY to sk-..."'
            )

        lines = ["[Secrets Info]"]
        lines.append(f"Total configured secrets: {secret_count}")

        # Group by type
        by_type: Dict[str, list] = {}
        for key, config in metadata.items():
            stype = getattr(config, "type", "secret")
            type_val = stype.value if hasattr(stype, "value") else str(stype)
            by_type.setdefault(type_val, []).append(key)

        for stype, keys in by_type.items():
            lines.append(f"{stype}: {', '.join(keys)}")

        common_secrets = [
            "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "DISCORD_BOT_TOKEN",
            "TELEGRAM_BOT_TOKEN", "TWITTER_API_KEY",
        ]
        missing_common = [k for k in common_secrets if k not in metadata]
        if missing_common and len(missing_common) < len(common_secrets):
            lines.append(f"Common secrets not set: {', '.join(missing_common)}")

        return "\n".join(lines)
