"""External provider configuration storage and management.

API keys are stored in ~/.config/proxym/external_credentials.json
with restricted permissions (0o600).
"""
from __future__ import annotations

import json
import os
from dataclasses import dataclass, asdict
from pathlib import Path
from typing import Optional


@dataclass
class ProviderConfig:
    """Configuration for an external provider."""
    provider: str  # github, gitlab, jira
    api_key: str
    base_url: Optional[str] = None  # For self-hosted GitLab or Jira
    email: Optional[str] = None  # Required for Jira
    name: Optional[str] = None  # Friendly name for this account
    enabled: bool = True


class ExternalConfigManager:
    """Manages external provider configurations."""

    CONFIG_DIR = Path.home() / ".config" / "proxym"
    CONFIG_FILE = CONFIG_DIR / "external_credentials.json"

    def __init__(self):
        self._config: dict = {}
        self._load()

    def _load(self) -> None:
        """Load configuration from file."""
        if self.CONFIG_FILE.exists():
            try:
                self._config = json.loads(self.CONFIG_FILE.read_text())
            except (json.JSONDecodeError, IOError):
                self._config = {}
        else:
            self._config = {}

    def _save(self) -> None:
        """Save configuration to file with restricted permissions."""
        self.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
        self.CONFIG_FILE.write_text(json.dumps(self._config, indent=2) + "\n")
        # Restrict permissions to owner only
        os.chmod(self.CONFIG_FILE, 0o600)

    def add_provider(self, config: ProviderConfig) -> None:
        """Add or update a provider configuration."""
        if "providers" not in self._config:
            self._config["providers"] = {}

        key = f"{config.provider}:{config.name or 'default'}"
        self._config["providers"][key] = asdict(config)
        self._save()

    def remove_provider(self, provider: str, name: Optional[str] = None) -> bool:
        """Remove a provider configuration."""
        if "providers" not in self._config:
            return False

        key = f"{provider}:{name or 'default'}"
        if key in self._config["providers"]:
            del self._config["providers"][key]
            self._save()
            return True
        return False

    def get_provider(self, provider: str, name: Optional[str] = None) -> Optional[ProviderConfig]:
        """Get a provider configuration."""
        if "providers" not in self._config:
            return None

        key = f"{provider}:{name or 'default'}"
        data = self._config["providers"].get(key)
        if not data:
            return None

        return ProviderConfig(**data)

    def list_providers(self, provider: Optional[str] = None) -> list[ProviderConfig]:
        """List all provider configurations."""
        if "providers" not in self._config:
            return []

        configs = []
        for key, data in self._config["providers"].items():
            if provider is None or key.startswith(f"{provider}:"):
                configs.append(ProviderConfig(**data))

        return configs

    async def test_provider(self, provider: str, name: Optional[str] = None) -> tuple[bool, str]:
        """Test provider credentials by making a simple API call."""
        config = self.get_provider(provider, name)
        if not config:
            return False, f"No configuration found for {provider}:{name or 'default'}"

        from proxym.external.providers import get_provider

        try:
            provider_instance = get_provider(
                config.provider,
                config.api_key,
                config.base_url,
                config.email,
            )
            async with provider_instance:
                is_valid = await provider_instance.validate_credentials()
                return is_valid, "Credentials valid" if is_valid else "Invalid credentials"
        except Exception as e:
            return False, str(e)


# Global instance
_config_manager: Optional[ExternalConfigManager] = None


def get_config_manager() -> ExternalConfigManager:
    """Get or create the global config manager instance."""
    global _config_manager
    if _config_manager is None:
        _config_manager = ExternalConfigManager()
    return _config_manager
