"""Secure API key storage via system keyring.

macOS  → Keychain (com.apple.keychainitem)
Windows → Windows Credential Manager (WinVault)
Linux  → SecretService / fallback file

All keys are stored under the service name "MuraveyChina".
"""

from __future__ import annotations

import logging
import sys

log = logging.getLogger(__name__)

_SERVICE = "MuraveyChina"


def _get_keyring():
    """Import keyring and configure platform backend."""
    try:
        import keyring

        if sys.platform == "win32":
            try:
                import keyring.backends.Windows as _wb

                keyring.set_keyring(_wb.WinVaultKeyring())
            except Exception:
                pass  # use default backend

        return keyring
    except ImportError:
        log.warning("keyring not installed — secrets cannot be stored securely")
        return None


def save_api_key(provider: str, key: str) -> bool:
    """Store *key* for *provider* in the system keyring.

    Returns True on success.
    """
    kr = _get_keyring()
    if kr is None:
        return False
    try:
        kr.set_password(_SERVICE, f"{provider}_api_key", key)
        log.debug("API key saved for provider '%s'", provider)
        return True
    except Exception as exc:
        log.error("Failed to save API key for '%s': %s", provider, exc)
        return False


def load_api_key(provider: str) -> str | None:
    """Retrieve the stored API key for *provider*.

    Returns None if not found.
    """
    kr = _get_keyring()
    if kr is None:
        return None
    try:
        return kr.get_password(_SERVICE, f"{provider}_api_key")
    except Exception as exc:
        log.error("Failed to load API key for '%s': %s", provider, exc)
        return None


def delete_api_key(provider: str) -> bool:
    """Remove the stored API key for *provider*.

    Returns True if deleted, False if not found or error.
    """
    kr = _get_keyring()
    if kr is None:
        return False
    try:
        kr.delete_password(_SERVICE, f"{provider}_api_key")
        log.debug("API key deleted for provider '%s'", provider)
        return True
    except Exception as exc:
        # keyring raises PasswordDeleteError if not found — treat as non-fatal
        log.debug("Could not delete key for '%s': %s", provider, exc)
        return False


def save_license_key(key: str) -> bool:
    """Store the application license key."""
    return save_api_key("license", key)


def load_license_key() -> str | None:
    """Retrieve the stored license key."""
    return load_api_key("license")


def has_api_key(provider: str) -> bool:
    """Return True if an API key exists for *provider*."""
    key = load_api_key(provider)
    return bool(key)


# ------------------------------------------------------------------ #
# License validation cache
# ------------------------------------------------------------------ #

_LICENSE_CACHE_ACCOUNT = "license_cache"


def store_license_cache(data: dict) -> bool:
    """Persist license validation result as JSON in the keyring.

    *data* expected shape::

        {
            "valid":      bool,
            "cached_at":  float,       # time.time()
            "key_hash":   str,         # SHA-256 of the license key
            "expires":    str | None,  # ISO-8601 or None
        }

    Returns True on success.
    """
    import json

    kr = _get_keyring()
    if kr is None:
        return False
    try:
        payload = json.dumps(data, ensure_ascii=False)
        kr.set_password(_SERVICE, _LICENSE_CACHE_ACCOUNT, payload)
        log.debug("License cache stored (valid=%s)", data.get("valid"))
        return True
    except Exception as exc:
        log.error("Failed to store license cache: %s", exc)
        return False


def get_license_cache() -> dict | None:
    """Retrieve the cached license validation result.

    Returns the parsed dict, or None if no cache exists or parsing fails.
    """
    import json

    kr = _get_keyring()
    if kr is None:
        return None
    try:
        raw = kr.get_password(_SERVICE, _LICENSE_CACHE_ACCOUNT)
        if not raw:
            return None
        return json.loads(raw)
    except Exception as exc:
        log.error("Failed to read license cache: %s", exc)
        return None


def clear_license_cache() -> bool:
    """Remove the cached license validation result."""
    kr = _get_keyring()
    if kr is None:
        return False
    try:
        kr.delete_password(_SERVICE, _LICENSE_CACHE_ACCOUNT)
        log.debug("License cache cleared")
        return True
    except Exception as exc:
        log.debug("Could not clear license cache: %s", exc)
        return False
