"""
LinuxDO OAuth2 服务
"""
import httpx
import secrets
from typing import Optional, Dict, Any
from app.config import settings


class LinuxDOOAuthService:
    """LinuxDO OAuth2 服务类"""
    
    # LinuxDO OAuth2 端点
    AUTHORIZE_URL = "https://connect.linux.do/oauth2/authorize"
    TOKEN_URL = "https://connect.linux.do/oauth2/token"
    USERINFO_URL = "https://connect.linux.do/api/user"  # 修复：使用正确的用户信息端点
    
    def __init__(self):
        self.client_id = settings.LINUXDO_CLIENT_ID
        self.client_secret = settings.LINUXDO_CLIENT_SECRET
        self.redirect_uri = settings.LINUXDO_REDIRECT_URI
        
        # 如果未配置，使用默认值（本地开发）
        if not self.redirect_uri:
            self.redirect_uri = "http://localhost:8000/api/auth/callback"
            import logging
            logger = logging.getLogger(__name__)
            logger.warning(
                "⚠️  LINUXDO_REDIRECT_URI 未配置，使用默认值: http://localhost:8000/api/auth/callback\n"
                "如需使用 OAuth 登录，请在 .env 文件中配置：\n"
                "本地开发: LINUXDO_REDIRECT_URI=http://localhost:8000/api/auth/callback\n"
                "Docker部署: LINUXDO_REDIRECT_URI=https://your-domain.com/api/auth/callback"
            )
        
        # 警告：检查是否使用了localhost（在非开发环境）
        if not settings.debug and "localhost" in self.redirect_uri.lower():
            import logging
            logger = logging.getLogger(__name__)
            logger.warning(
                f"⚠️  生产环境检测到使用 localhost 作为回调地址: {self.redirect_uri}\n"
                "这可能导致OAuth回调失败！请使用实际的域名或服务器IP。"
            )
        
    def generate_state(self) -> str:
        """生成随机 state 参数"""
        return secrets.token_urlsafe(32)
    
    def get_authorization_url(self, state: str) -> str:
        """
        获取授权 URL
        
        Args:
            state: 随机 state 参数
            
        Returns:
            授权 URL
        """
        params = {
            "client_id": self.client_id,
            "redirect_uri": self.redirect_uri,
            "response_type": "code",
            "scope": "read",
            "state": state
        }
        
        query_string = "&".join([f"{k}={v}" for k, v in params.items()])
        return f"{self.AUTHORIZE_URL}?{query_string}"
    
    async def get_access_token(self, code: str) -> Optional[Dict[str, Any]]:
        """
        使用授权码获取访问令牌
        
        Args:
            code: 授权码
            
        Returns:
            包含 access_token 的字典,失败返回 None
        """
        data = {
            "client_id": self.client_id,
            "client_secret": self.client_secret,
            "code": code,
            "grant_type": "authorization_code",
            "redirect_uri": self.redirect_uri
        }
        
        try:
            async with httpx.AsyncClient() as client:
                response = await client.post(
                    self.TOKEN_URL,
                    data=data,
                    headers={"Content-Type": "application/x-www-form-urlencoded"}
                )
                
                if response.status_code == 200:
                    return response.json()
                else:
                    print(f"获取访问令牌失败: {response.status_code} {response.text}")
                    return None
                    
        except Exception as e:
            print(f"获取访问令牌异常: {e}")
            return None
    
    async def get_user_info(self, access_token: str) -> Optional[Dict[str, Any]]:
        """
        使用访问令牌获取用户信息
        
        Args:
            access_token: 访问令牌
            
        Returns:
            用户信息字典,失败返回 None
        """
        try:
            # 添加真实浏览器请求头，避免被 Cloudflare 拦截
            headers = {
                "Authorization": f"Bearer {access_token}",
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
                "Accept": "application/json",
                "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
            }
            
            # 不自动处理编码，让 httpx 自动解压
            async with httpx.AsyncClient(follow_redirects=True, timeout=30.0) as client:
                response = await client.get(
                    self.USERINFO_URL,
                    headers=headers
                )
                
                print(f"获取用户信息响应状态: {response.status_code}")
                print(f"响应头: {response.headers}")
                
                if response.status_code == 200:
                    try:
                        user_data = response.json()
                        print(f"用户信息: {user_data}")
                        return user_data
                    except Exception as json_error:
                        print(f"解析 JSON 失败: {json_error}")
                        print(f"响应内容前100字符: {response.text[:100]}")
                        return None
                else:
                    print(f"获取用户信息失败: {response.status_code}")
                    print(f"响应内容: {response.text[:200]}")
                    return None
                    
        except Exception as e:
            print(f"获取用户信息异常: {type(e).__name__}: {str(e)}")
            import traceback
            traceback.print_exc()
            return None