"""Sync manager for handling cloud synchronization."""

import json
from pathlib import Path
from typing import Dict, Any, Optional, Type

from .interface import CloudProvider
from .providers import WebDAVProvider


class SyncManager:
    """Manager for cloud synchronization."""

    # Registry of available providers
    _providers: Dict[str, Type[CloudProvider]] = {
        "webdav": WebDAVProvider,
    }

    def __init__(self, config_dir: Path):
        """
        Initialize the sync manager.

        Args:
            config_dir: Directory to store sync configuration
        """
        self.config_dir = config_dir
        self.config_file = config_dir / "sync_config.json"
        self.config = self._load_config()

    def _load_config(self) -> Dict[str, Any]:
        """Load sync configuration from file."""
        if self.config_file.exists():
            try:
                with open(self.config_file, "r") as f:
                    return json.load(f)
            except Exception:
                return {}
        return {}

    def _save_config(self) -> None:
        """Save sync configuration to file."""
        self.config_dir.mkdir(parents=True, exist_ok=True)
        with open(self.config_file, "w") as f:
            json.dump(self.config, f, indent=2)

    def configure(self, provider_name: str, config: Dict[str, Any]) -> bool:
        """
        Configure a cloud provider for synchronization.

        Args:
            provider_name: Name of the provider (e.g., "webdav")
            config: Provider-specific configuration

        Returns:
            bool: True if configuration successful, False otherwise
        """
        if provider_name not in self._providers:
            return False

        try:
            # Test the configuration
            provider_class = self._providers[provider_name]
            provider = provider_class(config)

            if not provider.test_connection():
                return False

            # Save configuration
            self.config["enabled"] = True
            self.config["provider"] = provider_name
            self.config["provider_config"] = config
            self._save_config()

            return True
        except Exception:
            return False

    def disable(self) -> None:
        """Disable cloud synchronization."""
        self.config["enabled"] = False
        self._save_config()

    def is_enabled(self) -> bool:
        """Check if cloud synchronization is enabled."""
        return self.config.get("enabled", False)

    def get_provider(self) -> Optional[CloudProvider]:
        """
        Get the configured cloud provider instance.

        Returns:
            CloudProvider instance or None if not configured
        """
        if not self.is_enabled():
            return None

        provider_name = self.config.get("provider")
        if not provider_name or provider_name not in self._providers:
            return None

        try:
            provider_class = self._providers[provider_name]
            provider_config = self.config.get("provider_config", {})
            return provider_class(provider_config)
        except Exception:
            return None

    def sync(self, local_path: Path, remote_path: str = "") -> bool:
        """
        Synchronize local directory with cloud storage.

        Args:
            local_path: Local directory to sync
            remote_path: Remote path (relative to provider's base path)

        Returns:
            bool: True if sync successful, False otherwise
        """
        provider = self.get_provider()
        if not provider:
            return False

        try:
            return provider.sync(local_path, remote_path)
        except Exception:
            return False

    @classmethod
    def get_available_providers(cls) -> Dict[str, Type[CloudProvider]]:
        """
        Get all available cloud providers.

        Returns:
            Dict mapping provider names to provider classes
        """
        return cls._providers.copy()

    def get_config_info(self) -> Dict[str, Any]:
        """
        Get current configuration information.

        Returns:
            Dict with configuration details (without sensitive data)
        """
        if not self.is_enabled():
            return {"enabled": False}

        provider_name = self.config.get("provider", "")
        provider_config = self.config.get("provider_config", {})

        # Remove sensitive data
        safe_config = {}
        for key, value in provider_config.items():
            if key.lower() in ["password", "token", "secret", "key"]:
                safe_config[key] = "***"
            else:
                safe_config[key] = value

        return {
            "enabled": True,
            "provider": provider_name,
            "config": safe_config
        }
