"""Secrets management for voice agents.

Resolution order for each secret:
  1. Environment variable  (e.g. ROOHAI_SECRET_<AGENT>_<MODEL>_<KEY>)
  2. AWS Secrets Manager   (if ROOHAI_SECRETS_ARN is set)
  3. Local file            (~/.roohai/secrets.yaml or $ROOHAI_DATA_DIR/secrets.yaml)

Local dev uses the file.  Production should use env vars or Secrets Manager.
"""

from __future__ import annotations

import json
import logging
import os
from pathlib import Path

import yaml

logger = logging.getLogger(__name__)

SECRETS_DIR = Path(os.environ.get("ROOHAI_DATA_DIR", os.environ.get("VOICEAI_DATA_DIR", Path.home() / ".roohai")))
SECRETS_FILE = SECRETS_DIR / "secrets.yaml"


# ---------------------------------------------------------------------------
# Backend 1: Local YAML file (dev / single-machine)
# ---------------------------------------------------------------------------

def _ensure_file() -> None:
    """Create secrets dir and file if they don't exist, with secure permissions."""
    SECRETS_DIR.mkdir(parents=True, exist_ok=True)
    if not SECRETS_FILE.exists():
        SECRETS_FILE.write_text("{}\n")
    os.chmod(SECRETS_FILE, 0o600)


def _load_file_secrets() -> dict:
    _ensure_file()
    data = yaml.safe_load(SECRETS_FILE.read_text())
    return data if isinstance(data, dict) else {}


def _save_file_secrets(all_secrets: dict) -> None:
    _ensure_file()
    SECRETS_FILE.write_text(yaml.safe_dump(all_secrets, default_flow_style=False))
    os.chmod(SECRETS_FILE, 0o600)


# ---------------------------------------------------------------------------
# Backend 2: AWS Secrets Manager (production)
# ---------------------------------------------------------------------------

def _load_aws_secrets() -> dict | None:
    """Load secrets from AWS Secrets Manager if ROOHAI_SECRETS_ARN is set.

    Expects the secret value to be JSON with the same structure as secrets.yaml:
      {"agent-name": {"model-name": {"api_key": "xxx"}}}
    """
    arn = os.environ.get("ROOHAI_SECRETS_ARN", os.environ.get("VOICEAI_SECRETS_ARN"))
    if not arn:
        return None
    try:
        import boto3
        client = boto3.client("secretsmanager",
                              region_name=os.environ.get("AWS_DEFAULT_REGION", "us-east-1"))
        resp = client.get_secret_value(SecretId=arn)
        data = json.loads(resp["SecretString"])
        logger.info("Loaded secrets from AWS Secrets Manager (%s)", arn)
        return data if isinstance(data, dict) else {}
    except Exception:
        logger.warning("Failed to load secrets from AWS Secrets Manager", exc_info=True)
        return None


# ---------------------------------------------------------------------------
# Backend 3: Environment variables
# ---------------------------------------------------------------------------

def _get_env_agent_secrets(agent_name: str) -> dict:
    """Check for secrets passed as env vars.

    Pattern: ROOHAI_SECRET_<AGENT>_<MODEL>_<KEY>=value
    Example: ROOHAI_SECRET_MYAGENT_DEEPGRAM_API_KEY=dg-xxx

    Also checks legacy VOICEAI_SECRET_ prefix for backward compatibility.
    """
    result: dict[str, dict[str, str]] = {}
    for env_prefix in (f"ROOHAI_SECRET_{agent_name.upper().replace('-', '_')}_",
                       f"VOICEAI_SECRET_{agent_name.upper().replace('-', '_')}_"):
        for key, value in os.environ.items():
            if key.startswith(env_prefix):
                remainder = key[len(env_prefix):]
                parts = remainder.rsplit("_", 1)
                if len(parts) == 2:
                    model_name = parts[0].lower().replace("_", "-")
                    field_name = parts[1].lower()
                    result.setdefault(model_name, {})[field_name] = value
    return result


# ---------------------------------------------------------------------------
# Public API
# ---------------------------------------------------------------------------

def load_secrets() -> dict:
    """Load all secrets, merging from all backends (env > AWS > file)."""
    # Start with file
    secrets = _load_file_secrets()

    # Override with AWS Secrets Manager if configured
    aws = _load_aws_secrets()
    if aws is not None:
        for agent, models in aws.items():
            secrets.setdefault(agent, {}).update(models)

    return secrets


def get_agent_secrets(agent_name: str) -> dict:
    """Get secrets for a specific agent. Checks env vars, then AWS, then file."""
    # Env vars take highest priority
    env_secrets = _get_env_agent_secrets(agent_name)

    # Then AWS + file
    base = load_secrets().get(agent_name, {})

    # Merge: env wins
    for model, fields in env_secrets.items():
        base.setdefault(model, {}).update(fields)

    return base


def set_agent_secrets(agent_name: str, secrets: dict) -> None:
    """Store secrets for a specific agent (writes to local file)."""
    all_secrets = _load_file_secrets()
    all_secrets[agent_name] = secrets
    _save_file_secrets(all_secrets)


def delete_agent_secrets(agent_name: str) -> None:
    """Remove secrets for a specific agent (from local file)."""
    all_secrets = _load_file_secrets()
    all_secrets.pop(agent_name, None)
    _save_file_secrets(all_secrets)
