"""
Secure API key storage using OS keychain.

Uses the keyring library to store API keys securely in the OS keychain:
- macOS: Keychain
- Windows: Credential Manager
- Linux: Secret Service (or fallback to encrypted file)
"""

from __future__ import annotations

import logging
import platform
from pathlib import Path
from typing import Optional

logger = logging.getLogger(__name__)

# Try to import keyring, but make it optional
try:
    import keyring

    KEYRING_AVAILABLE = True
except ImportError:
    KEYRING_AVAILABLE = False
    logger.warning(
        "keyring not available - keys will be stored in plaintext (not recommended)"
    )


def store_api_key(service: str, key: str, username: str = "api_key") -> bool:
    """Store API key in OS keychain.

    Args:
        service: Service identifier (e.g., "kvict")
        key: API key to store
        username: Username/key identifier (default: "api_key")

    Returns:
        True if successful, False otherwise
    """
    if not KEYRING_AVAILABLE:
        # Fallback to encrypted file storage
        return _store_in_file(service, key)

    try:
        keyring.set_password(service, username, key)
        logger.info(f"API key stored securely in {_get_keychain_name()}")
        return True
    except Exception as e:
        logger.error(f"Failed to store key in keychain: {e}")
        # Fallback to file storage
        return _store_in_file(service, key)


def get_api_key(service: str, username: str = "api_key") -> Optional[str]:
    """Retrieve API key from OS keychain.

    Args:
        service: Service identifier (e.g., "kvict")
        username: Username/key identifier (default: "api_key")

    Returns:
        API key if found, None otherwise
    """
    if not KEYRING_AVAILABLE:
        return _get_from_file(service)

    try:
        key = keyring.get_password(service, username)
        return key
    except Exception as e:
        logger.warning(f"Failed to get key from keychain: {e}")
        # Try file fallback
        return _get_from_file(service)


def delete_api_key(service: str, username: str = "api_key") -> bool:
    """Delete API key from OS keychain.

    Args:
        service: Service identifier (e.g., "kvict")
        username: Username/key identifier (default: "api_key")

    Returns:
        True if successful, False otherwise
    """
    if not KEYRING_AVAILABLE:
        return _delete_from_file(service)

    try:
        keyring.delete_password(service, username)
        logger.info("API key deleted from keychain")
        return True
    except Exception as e:
        logger.warning(f"Failed to delete key from keychain: {e}")
        # Try file fallback
        return _delete_from_file(service)


def _get_keychain_name() -> str:
    """Get human-readable name for the keychain backend."""
    if not KEYRING_AVAILABLE:
        return "file storage"

    system = platform.system()
    if system == "Darwin":
        return "macOS Keychain"
    elif system == "Windows":
        return "Windows Credential Manager"
    elif system == "Linux":
        return "Secret Service"
    else:
        return "keyring"


def _get_config_dir() -> Path:
    """Get configuration directory for fallback file storage."""
    home = Path.home()
    if platform.system() == "Windows":
        config_dir = home / "AppData" / "Local" / "kvict"
    else:
        config_dir = home / ".kvict"
    config_dir.mkdir(parents=True, exist_ok=True)
    return config_dir


def _store_in_file(service: str, key: str) -> bool:
    """Fallback: store key in plaintext file (not secure, but better than nothing)."""
    try:
        config_dir = _get_config_dir()
        key_file = config_dir / f"{service}_key.txt"
        key_file.write_text(key)
        key_file.chmod(0o600)  # Restrict permissions
        logger.warning(f"API key stored in file (not secure): {key_file}")
        logger.warning(
            "Install 'keyring' package for secure storage: pip install keyring"
        )
        return True
    except Exception as e:
        logger.error(f"Failed to store key in file: {e}")
        return False


def _get_from_file(service: str) -> Optional[str]:
    """Fallback: get key from file."""
    try:
        config_dir = _get_config_dir()
        key_file = config_dir / f"{service}_key.txt"
        if key_file.exists():
            return key_file.read_text().strip()
    except Exception as e:
        logger.warning(f"Failed to read key from file: {e}")
    return None


def _delete_from_file(service: str) -> bool:
    """Fallback: delete key file."""
    try:
        config_dir = _get_config_dir()
        key_file = config_dir / f"{service}_key.txt"
        if key_file.exists():
            key_file.unlink()
            return True
    except Exception as e:
        logger.warning(f"Failed to delete key file: {e}")
    return False
