"""Cookie Cloud 模块 - 从 Cookie Cloud 服务器获取并解密 cookie 数据"""
import hashlib
import json
import base64
from typing import Dict, List, Optional
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
from applogger import get_logger

logger = get_logger(__name__)


class CookieCloud:
    """Cookie Cloud 客户端"""

    def __init__(self, api_url: str, uuid: str, password: str):
        """
        初始化 Cookie Cloud 客户端

        Args:
            api_url: Cookie Cloud API 地址
            uuid: 用户 UUID
            password: 用户密码
        """
        self.api_url = api_url.rstrip('/')
        self.uuid = uuid
        self.password = password

    def decrypt(self, encrypted_data: str) -> Dict:
        """
        解密 Cookie Cloud 数据

        Args:
            encrypted_data: 加密的数据字符串

        Returns:
            解密后的数据字典，包含 cookie_data 和 local_storage_data
        """
        # 生成解密密钥: md5(uuid+password) 取前 16 个字符
        key_str = f"{self.uuid}{self.password}"
        key = hashlib.md5(key_str.encode()).hexdigest()[:16].encode()
        print(f"生成的密钥: {key}")
        print(f"密钥长度: {len(key)}")
        
        # 解码 Base64
        encrypted = base64.b64decode(encrypted_data)
        print(f"Base64 解码后长度: {len(encrypted)}")
        print(f"解码后前 20 字节: {encrypted[:20]}")
        
        # 检查是否有盐值（OpenSSL 格式）
        if encrypted.startswith(b'Salted__'):
            print("检测到 OpenSSL 格式数据")
            # 对于 OpenSSL 格式，我们需要跳过盐值部分
            # 但根据用户要求，我们直接使用16字符密钥，不考虑盐值
            ciphertext = encrypted[16:]  # 跳过 "Salted__" 和盐值
            print(f"密文长度: {len(ciphertext)}")
        else:
            print("未检测到 OpenSSL 格式，使用整个数据作为密文")
            ciphertext = encrypted
        
        # 使用固定的 IV (16 个 0 字节)
        iv = b'\x00' * 16
        print(f"使用的 IV: {iv}")
        
        # AES-128-CBC 解密（16字节密钥）
        cipher = AES.new(key, AES.MODE_CBC, iv)
        decrypted = cipher.decrypt(ciphertext)
        print(f"解密后长度: {len(decrypted)}")
        print(f"解密后前 100 字节: {decrypted[:100]}")
        
        try:
            # 移除 PKCS#7 填充
            decrypted = unpad(decrypted, AES.block_size)
            print(f"移除填充后长度: {len(decrypted)}")
            print(f"移除填充后前 100 字节: {decrypted[:100]}")
            
            # 尝试解析 JSON
            result = json.loads(decrypted.decode('utf-8'))
            print("JSON 解析成功")
            return result
        except Exception as e:
            print(f"解密失败: {e}")
            # 尝试直接截取可能的有效数据
            try:
                # 尝试找到 JSON 开始的位置
                for i in range(len(decrypted)):
                    try:
                        test_data = decrypted[i:]
                        test_str = test_data.decode('utf-8', errors='ignore')
                        if test_str.strip().startswith('{'):
                            print(f"找到可能的 JSON 开始位置: {i}")
                            result = json.loads(test_str)
                            print("JSON 解析成功（直接截取）")
                            return result
                    except:
                        continue
            except:
                pass
            raise

    def get_cookies(self) -> Dict[str, List[Dict]]:
        """
        从 Cookie Cloud 服务器获取 cookie 数据

        Returns:
            按域名分组的 cookie 数据字典
            格式: {"domain.com": [{"name": "cookie1", "value": "val1", ...}, ...], ...}
        """
        url = f"{self.api_url}/get/{self.uuid}"
        
        try:
            response = requests.get(url, timeout=30)
            response.raise_for_status()
            data = response.json()
            
            logger.info(f"Cookie Cloud 响应: {json.dumps(data, indent=2)}")
            
            if not data or 'encrypted' not in data:
                logger.error("响应中没有 encrypted 字段")
                return {}
            
            # 打印完整的加密数据长度和前200个字符
            logger.info(f"加密数据长度: {len(data['encrypted'])}")
            logger.info(f"加密数据前 200 个字符: {data['encrypted'][:200]}...")
            
            try:
                decrypted_data = self.decrypt(data['encrypted'])
                logger.info(f"解密后的数据: {json.dumps(decrypted_data, indent=2)}")
            except Exception as e:
                logger.error(f"解密失败: {e}")
                return {}
            
            # 解析 cookie_data
            cookie_dict = {}
            if 'cookie_data' in decrypted_data:
                for domain, cookies in decrypted_data['cookie_data'].items():
                    cookie_dict[domain] = []
                    for cookie in cookies:
                        # 处理 sameSite 字段
                        if cookie.get('sameSite') == 'unspecified':
                            cookie['sameSite'] = 'Lax'
                        cookie_dict[domain].append(cookie)
            
            return cookie_dict
            
        except requests.RequestException as e:
            logger.error(f"请求 Cookie Cloud 失败: {e}")
            return {}
        except Exception as e:
            logger.error(f"处理 Cookie Cloud 数据失败: {e}")
            return {}

    def get_cookies_for_domain(self, domain: str) -> List[Dict]:
        """
        获取指定域名的 cookie

        Args:
            domain: 域名

        Returns:
            cookie 列表
        """
        all_cookies = self.get_cookies()
        
        # 查找匹配的域名
        for cookie_domain, cookies in all_cookies.items():
            if domain in cookie_domain or cookie_domain in domain:
                return cookies
        
        return []


if __name__ == "__main__":
    # 测试代码
    cc = CookieCloud(
        api_url="https://movie-pilot.org/cookiecloud",
        uuid="hu6n2vcUmzpu7mqUN2rVCg",
        password="jtDM5dV9AyqXkZdQVeA9f6"
    )
    
    cookies = cc.get_cookies()
    logger.info(json.dumps(cookies, indent=2, ensure_ascii=False))