"""
CloudSearch Transfer — 适配器工厂 v1.0.0
参考 cloud-auto-save 的 AdapterFactory + AccountManager
"""

import hashlib
import logging
from typing import Optional, Dict, Type

from .base import BaseCloudDriveAdapter, match_url
from ..config import ConfigManager
from ..errors import TransferError, TransferErrorCode

logger = logging.getLogger(__name__)


class AdapterFactory:
    """
    适配器工厂
    - URL正则自动识别网盘类型
    - 实例缓存：同平台+同Cookie单例
    - 多账号路由
    """

    # 平台注册表（延迟导入避免循环引用）
    _registry: Dict[str, Type[BaseCloudDriveAdapter]] = {}

    # 实例缓存 key: "platform:cookie_hash[:16]"
    _cache: Dict[str, BaseCloudDriveAdapter] = {}

    def __init__(self, config_manager: ConfigManager):
        self.config_manager = config_manager
        self._register_all()

    def _register_all(self):
        """注册所有平台适配器"""
        from .quark import QuarkAdapter
        from .baidu import BaiduAdapter
        from .aliyun import AliyunAdapter
        from .uc import UcAdapter
        from .xunlei import XunleiAdapter
        from .pan115 import Pan115Adapter
        from .pan123 import Pan123Adapter
        from .cloud189 import Cloud189Adapter

        self._registry = {
            "quark": QuarkAdapter,
            "baidu": BaiduAdapter,
            "aliyun": AliyunAdapter,
            "uc": UcAdapter,
            "xunlei": XunleiAdapter,
            "pan115": Pan115Adapter,
            "pan123": Pan123Adapter,
            "cloud189": Cloud189Adapter,
        }

    def detect_platform(self, url: str) -> Optional[str]:
        """根据URL自动识别网盘平台"""
        for platform_key, adapter_cls in self._registry.items():
            if match_url(url, adapter_cls):
                return platform_key
        return None

    def get_adapter(self, platform_key: str) -> Optional[BaseCloudDriveAdapter]:
        """获取适配器实例（带缓存）"""
        config = self.config_manager.get_platform(platform_key)
        if not config:
            return None

        adapter_cls = self._registry.get(platform_key)
        if not adapter_cls:
            return None

        # 构建缓存键
        cache_key = self._cache_key(platform_key, config)
        if cache_key in self._cache:
            return self._cache[cache_key]

        # 创建新实例
        adapter = adapter_cls(config, self.config_manager.transfer)
        self._cache[cache_key] = adapter
        logger.info(f"[Factory] Created adapter: {platform_key} "
                    f"(cache_key={cache_key})")
        return adapter

    def get_adapter_for_url(self, url: str) -> Optional[BaseCloudDriveAdapter]:
        """根据URL自动获取适配器"""
        platform = self.detect_platform(url)
        if not platform:
            raise TransferError(TransferErrorCode.URL_INVALID,
                                message=f"无法识别链接平台: {url}")
        adapter = self.get_adapter(platform)
        if not adapter:
            raise TransferError(TransferErrorCode.NO_CONFIG,
                                message=f"平台 {platform} 未配置凭证",
                                platform=platform)
        return adapter

    def invalidate_cache(self, platform_key: str = None):
        """清除缓存"""
        if platform_key:
            keys = [k for k in self._cache if k.startswith(platform_key)]
            for k in keys:
                del self._cache[k]
        else:
            self._cache.clear()

    def _cache_key(self, platform: str, config) -> str:
        """构建缓存键"""
        credential = config.cookie or config.refresh_token or ""
        token_hash = hashlib.md5(credential.encode()).hexdigest()[:16]
        return f"{platform}:{config.account_name}:{token_hash}"
