"""
OAuth服务模块
从 t_oauth_view.py 提取的SQL查询逻辑
"""
import sys
import os

# 添加src目录到Python路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../..'))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../..'))

import logging
import json
import secrets
from typing import Optional, Dict, Any, Tuple
from datetime import datetime, timezone
from app.base.async_mysql_connection import get_db_connection
from app.services.jwt_token import verify_token, create_access_token

logger = logging.getLogger(__name__)


class OAuthService:
    """OAuth服务类 - 使用 SQL 查询方式"""
    
    def __init__(self):
        """初始化服务"""
        pass
    
    async def validate_client_and_redirect_uri(self, client_id: str, redirect_uri: str) -> Tuple[bool, Optional[Dict[str, Any]], str]:
        """验证客户端ID和重定向URI"""
        conn = get_db_connection()
        if not conn:
            return False, None, "数据库连接失败"
        
        cursor = conn.cursor()
        
        try:
            # 验证client_id和redirect_uri
            cursor.execute("""
                SELECT id, name, redirect_uris, scope, is_active, is_trusted
                FROM t_sys_app 
                WHERE app_key = %s AND is_active = 1
            """, (client_id,))
            
            app_data = cursor.fetchone()
            logger.info(f"app_data={app_data}")
            if not app_data:
                return False, None, "无效的客户端ID"
            
            app_id = app_data["id"]
            app_name = app_data["name"]
            redirect_uris_json = app_data["redirect_uris"]
            app_scope_json = app_data["scope"]
            is_active = app_data["is_active"]
            is_trusted = app_data["is_trusted"]
            logger.info(f"redirect_uris_json={redirect_uris_json}")
            
            # 验证redirect_uri
            redirect_uris = json.loads(redirect_uris_json) if redirect_uris_json else []
            if redirect_uri not in redirect_uris:
                return False, None, "无效的重定向URI"
            
            app_info = {
                "id": app_id,
                "name": app_name,
                "redirect_uris": redirect_uris,
                "scope": json.loads(app_scope_json) if app_scope_json else [],
                "is_active": is_active,
                "is_trusted": is_trusted
            }
            
            return True, app_info, "验证成功"
        finally:
            cursor.close()
            conn.close()
    
    async def validate_client_credentials(self, client_id: str, client_secret: Optional[str] = None) -> Tuple[bool, Optional[Dict[str, Any]], str]:
        """验证客户端凭据"""
        conn = get_db_connection()
        if not conn:
            return False, None, "数据库连接失败"
        
        cursor = conn.cursor()
        
        try:
            # 验证客户端
            cursor.execute("""
                SELECT id, name, app_secret, redirect_uris, scope, is_active
                FROM t_sys_app 
                WHERE app_key = %s AND is_active = 1
            """, (client_id,))
            
            app_data = cursor.fetchone()
            
            if not app_data:
                return False, None, "无效的客户端凭据"
            
            app_id = app_data["id"]
            app_name = app_data["name"]
            app_secret = app_data["app_secret"]
            redirect_uris_json = app_data["redirect_uris"]
            scope_json = app_data["scope"]
            is_active = app_data["is_active"]
            
            
            # 验证客户端密钥（如果提供了）
            if client_secret and client_secret != app_secret:
                return False, None, "无效的客户端凭据"
            
            app_info = {
                "id": app_id,
                "name": app_name,
                "redirect_uris": json.loads(redirect_uris_json) if redirect_uris_json else [],
                "scope": json.loads(scope_json) if scope_json else []
            }
            
            return True, app_info, "验证成功"
        finally:
            cursor.close()
            conn.close()
    
    async def generate_access_token(self, user_id: str, client_id: str, scope: str = "profile email") -> str:
        """生成访问令牌"""
        token_data = {
            "sub": user_id,
            "client_id": client_id,
            "scope": scope
        }
        
        return create_access_token(token_data)
    
    async def get_user_info(self, user_id: str, scope: list) -> Optional[Dict[str, Any]]:
        """获取用户信息（根据scope过滤）"""
        conn = get_db_connection()
        if not conn:
            return None
        
        cursor = conn.cursor()
        
        try:
            # 查找用户信息
            cursor.execute("""
                SELECT u.id, u.username, u.email, u.phone, u.avatar_url, u.is_active,
                       p.real_name, p.company, p.department, p.position
                FROM t_sys_user u
                LEFT JOIN t_sys_user_profile p ON u.id = p.user_id
                WHERE u.id = %s AND u.is_active = 1
            """, (user_id,))
            
            user_data = cursor.fetchone()
            
            if not user_data:
                return None
            
            # 构建用户信息响应（根据scope过滤）
            user_info = {"sub": user_data["id"]}
            
            if "profile" in scope:
                user_info.update({
                    "username": user_data["username"],
                    "avatar_url": user_data["avatar_url"],
                    "real_name": user_data["real_name"],
                    "company": user_data["company"],
                    "department": user_data["department"],
                    "position": user_data["position"]
                })
            
            if "email" in scope:
                user_info["email"] = user_data["email"]
            
            if "phone" in scope:
                user_info["phone"] = user_data["phone"]
            
            return user_info
        finally:
            cursor.close()
            conn.close()
    
    async def store_authorization_code(self, user_id: str, client_id: str, code: str, redirect_uri: str, scope: str) -> bool:
        """存储授权码到数据库"""
        conn = get_db_connection()
        if not conn:
            logger.error("数据库连接失败")
            return False
        
        logger.info(f"参数: user_id={user_id}, client_id={client_id}, code={code[:20]}...")
        cursor = conn.cursor()
        
        try:

              # 验证客户端
            cursor.execute("""
                SELECT id, name, app_secret, redirect_uris, scope, is_active
                FROM t_sys_app 
                WHERE app_key = %s AND is_active = 1
            """, (client_id,))
            app_data = cursor.fetchone()
            if not app_data:
                return False, None, "无效的客户端凭据"

            app_id = app_data["id"]
            
            import uuid
            from datetime import timedelta
            
            # 生成授权码ID
            code_id = str(uuid.uuid4())
            
            # 设置过期时间（10分钟）
            expires_at = datetime.now() + timedelta(minutes=10)
            
            # 插入授权码记录
            cursor.execute("""
                INSERT INTO t_oauth_authorization_codes 
                (id, user_id, app_id, code, redirect_uri, scope, expires_at, used, created_time, updated_time, is_deleted)
                VALUES (%s, %s, %s, %s, %s, %s, %s, 0, NOW(), NOW(), 0)
            """, (code_id, user_id, app_id, code, redirect_uri, scope, expires_at))
            
            conn.commit()
            
            logger.info(f"授权码已存储: user_id={user_id}, client_id={client_id}, code={code[:20]}..., expires_at={expires_at}")
            return True
            
        except Exception as e:
            logger.exception("存储授权码错误")
            conn.rollback()
            return False
        finally:
            cursor.close()
            conn.close()
    
    async def validate_authorization_code(self, code: str, client_id: str, redirect_uri: str) -> Tuple[bool, Optional[str], str]:
        """验证授权码"""
        conn = get_db_connection()
        if not conn:
            return False, None, "数据库连接失败"
        
        cursor = conn.cursor()
        
        try:
            # 从数据库查找授权码
            cursor.execute("""
                SELECT user_id, app_id, redirect_uri, expires_at, used
                FROM t_oauth_authorization_codes
                WHERE code = %s AND is_deleted = 0
            """, (code,))
            
            auth_code = cursor.fetchone()
            
            if not auth_code:
                logger.warning(f"授权码不存在: code={code}")
                return False, None, "授权码无效"
            
            # 验证授权码是否已被使用
            if auth_code['used']:
                logger.warning(f"授权码已被使用: code={code}")
                return False, None, "授权码已被使用"
            
            # 验证授权码是否过期
            if auth_code['expires_at'] < datetime.now():
                logger.warning(f"授权码已过期: code={code}")
                return False, None, "授权码已过期"
            
            # 验证client_id
            # if auth_code['app_id'] != client_id:
            #     logger.warning(f"client_id不匹配: expected={auth_code['app_id']}, got={client_id}")
            #     return False, None, "client_id不匹配"
            
            # 验证redirect_uri
            if auth_code['redirect_uri'] != redirect_uri:
                logger.warning(f"redirect_uri不匹配: expected={auth_code['redirect_uri']}, got={redirect_uri}")
                return False, None, "redirect_uri不匹配"
            
            # 标记授权码为已使用
            cursor.execute("""
                UPDATE t_oauth_authorization_codes
                SET used = 1, updated_time = NOW()
                WHERE code = %s
            """, (code,))
            
            conn.commit()
            
            user_id = auth_code['user_id']
            logger.info(f"授权码验证成功: code={code}, user_id={user_id}, client_id={client_id}")
            
            return True, user_id, "验证成功"
            
        except Exception as e:
            logger.exception("验证授权码错误")
            conn.rollback()
            return False, None, "服务器内部错误"
        finally:
            cursor.close()
            conn.close()