"""
MANAGE_SECRET action.

Comprehensive action for managing secrets through natural language.
Supports get, set, delete, list, and check operations.
"""

import re
import logging
from typing import Optional, Dict

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

from ..types import SecretLevel, SecretContext


logger = logging.getLogger(__name__)


class ManageSecretAction(Action):
    """Action for comprehensive secret management via natural language."""

    name = "MANAGE_SECRET"
    description = "Manage secrets - get, set, delete, list, or check secrets."
    similes = [
        "manage secret", "show secrets", "delete secret",
        "list secrets", "check secret", "get secret", "remove api key",
    ]
    examples = [
        [
            {"user": "user", "content": {"text": "List all my secrets"}},
            {"user": "assistant", "content": {"text": "Here are your configured secrets: OPENAI_API_KEY (set)"}},
        ],
        [
            {"user": "user", "content": {"text": "Delete my GROQ_API_KEY"}},
            {"user": "assistant", "content": {"text": "I've deleted the GROQ_API_KEY secret."}},
        ],
    ]

    async def validate(self, runtime: AgentRuntime, message: Message) -> bool:
        text = message.content.get("text", "").lower() if isinstance(message.content, dict) else str(message.content).lower()
        operations = ["list", "show", "get", "delete", "remove", "check", "verify", "what", "which"]
        secret_keywords = ["secret", "key", "api", "token", "credential", "configured"]
        return any(op in text for op in operations) and any(kw in text for kw in secret_keywords)

    async def handler(self, runtime: AgentRuntime, message: Message, state: Dict) -> Dict:
        from ..service import SecretsService

        secrets_service: SecretsService = runtime.get_service(SecretsService.service_type)
        if not secrets_service:
            return {"success": False, "message": "Secrets service not available"}

        text = message.content.get("text", "") if isinstance(message.content, dict) else str(message.content)
        operation = self._detect_operation(text)
        context = SecretContext(
            level=SecretLevel.GLOBAL,
            agent_id=runtime.agent_id,
            user_id=getattr(message, "user_id", None),
        )

        if operation == "list":
            return await self._handle_list(secrets_service, context)
        elif operation == "get":
            key = self._extract_key(text)
            if not key:
                return {"success": False, "message": "Please specify which secret to get."}
            return await self._handle_get(secrets_service, key, context)
        elif operation == "delete":
            key = self._extract_key(text)
            if not key:
                return {"success": False, "message": "Please specify which secret to delete."}
            return await self._handle_delete(secrets_service, key, context)
        elif operation == "check":
            key = self._extract_key(text)
            if key:
                return await self._handle_check(secrets_service, key, context)
            return await self._handle_list(secrets_service, context)
        else:
            return {"success": False, "message": "Unknown operation. You can list, get, set, delete, or check secrets."}

    def _detect_operation(self, text: str) -> str:
        text_lower = text.lower()
        if any(kw in text_lower for kw in ["list", "show all", "what secrets", "which secrets"]):
            return "list"
        if any(kw in text_lower for kw in ["delete", "remove"]):
            return "delete"
        if any(kw in text_lower for kw in ["check", "verify", "is", "have"]):
            return "check"
        if any(kw in text_lower for kw in ["get", "show", "what is"]):
            return "get"
        return "list"

    def _extract_key(self, text: str) -> Optional[str]:
        match = re.search(r"([A-Z][A-Z0-9_]{2,})", text)
        if match:
            return match.group(1)
        common_keys = [
            "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GROQ_API_KEY",
            "GOOGLE_API_KEY", "DISCORD_TOKEN", "TELEGRAM_TOKEN",
        ]
        text_upper = text.upper()
        for key in common_keys:
            if key in text_upper:
                return key
        return None

    async def _handle_list(self, service, context: SecretContext) -> Dict:
        metadata = await service.list(context)
        if not metadata:
            return {"success": True, "message": "No secrets configured.", "secrets": []}
        secrets_info = []
        for key, config in metadata.items():
            desc = getattr(config, "description", "") or ""
            secrets_info.append(f"- {key}: configured" + (f" ({desc})" if desc else ""))
        return {
            "success": True,
            "message": "Configured secrets:\n" + "\n".join(secrets_info),
            "secrets": list(metadata.keys()),
        }

    async def _handle_get(self, service, key: str, context: SecretContext) -> Dict:
        exists = await service.exists(key, context)
        if not exists:
            return {"success": False, "message": f"Secret '{key}' is not configured."}
        config = await service.get_config(key, context)
        desc = getattr(config, "description", "") if config else ""
        return {
            "success": True,
            "message": f"Secret '{key}' is configured." + (f" Description: {desc}" if desc else ""),
            "exists": True,
        }

    async def _handle_delete(self, service, key: str, context: SecretContext) -> Dict:
        success = await service.delete(key, context)
        if success:
            return {"success": True, "message": f"Deleted secret '{key}'."}
        return {"success": False, "message": f"Secret '{key}' not found or could not be deleted."}

    async def _handle_check(self, service, key: str, context: SecretContext) -> Dict:
        exists = await service.exists(key, context)
        return {
            "success": True,
            "message": f"Secret '{key}' is {'configured' if exists else 'not configured'}.",
            "exists": exists,
        }
