#!/usr/bin/env python
# @Project ：django_base_ai
# @File    : login.py
# @Author  : cx
# @Time    : 11/2/2025
# @Desc    : JWT 登录与单点登录接口
import json
import logging
import uuid
from datetime import datetime

import requests
from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import make_password
from django.core.cache import cache
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken

from django_base_ai import dispatch
from django_base_ai.system.models import Role
from django_base_ai.utils.json_response import DetailResponse, ErrorResponse
from django_base_ai.utils.request_util import save_login_log

User = get_user_model()

logger = logging.getLogger(__name__)


class LoginJWTAPIView(APIView):
    authentication_classes = ()
    permission_classes = ()

    # 通过第三方ticket 获取用户
    def get(self, request, *args, **kwargs):
        """
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        logger.info("开始处理第三方登录请求")

        # 获取配置信息
        login_type = dispatch.get_system_config_values("third.login_type", "")
        login_agent_id = dispatch.get_system_config_values("third.login_agent_id", "")
        login_agent_secret = dispatch.get_system_config_values("third.login_agent_secret", "")
        login_token_name = dispatch.get_system_config_values("third.login_token_name", "")
        request_type = dispatch.get_system_config_values("third.request_type", "")
        default_role_ids = dispatch.get_system_config_values("third.default_role")
        mailbox_suffix = dispatch.get_system_config_values("third.mailbox_suffix", "@qq.com.cn")
        login_http_url = dispatch.get_system_config_values("third.login_http_url", "@qq.com.cn")

        logger.info(
            f"登录配置加载完成 - 登录类型: {login_type}, token名称: {login_token_name}, 请求类型: {request_type}"
        )

        # 获取授权码
        code = request.GET.get(f"{login_token_name}", None)
        if code is None:
            logger.warning(f"授权码为空 - token名称: {login_token_name}")
            return ErrorResponse(msg="参数错误请稍后再试,授权码无效!")

        logger.info(f"获取到授权码, code={code[:10]}...")

        result_json = {}
        try:
            # 获取当前用户信息
            response = requests.request(
                request_type,
                login_http_url,
                data={"appid": login_agent_id, "appsecret": login_agent_secret, f"{login_token_name}": code},
            )
            result_json = response.json()
            logger.info(f"第三方认证响应 - code: {result_json.get('code')}")
        except Exception as e:
            logger.error(f"请求第三方认证服务失败: {str(e)}")
            return ErrorResponse(msg="认证服务异常，请稍后再试")

        result_code = result_json.get("code")
        user_info = result_json.get("result")

        if result_code != 1 or user_info is None:
            logger.warning(f"第三方认证失败 - code: {result_code}, userInfo: {user_info}")
            return ErrorResponse(msg="授权码无效请稍后再试")

        try:
            user_info = json.loads(user_info)
            username = user_info.get("username", "").upper()
            first_name = user_info.get("first_name", "")
            logger.info(f"解析用户信息成功 - username: {username}, first_name: {first_name}")
        except json.JSONDecodeError as e:
            logger.error(f"解析用户信息失败: {str(e)}")
            return ErrorResponse(msg="用户信息解析失败")

        # 检查用户是否存在
        userinfo = User.objects.filter(username=username).first()
        if userinfo and userinfo.is_active is False:
            logger.warning(f"用户已被禁用 - username: {username}")
            return ErrorResponse(msg="创建失败或用户已被禁用!")

        # 创建或更新用户
        try:
            user, created = User.objects.update_or_create(
                defaults={
                    "username": username,
                    "password": make_password(str(uuid.uuid4())),
                    "is_active": True,
                    "email": f"{username}{mailbox_suffix}",
                    "pwd_defaulted": False,
                    "last_login": datetime.now(),
                    "name": first_name,
                },
                username=username,
            )

            if created:
                logger.info(f"创建新用户成功 - username: {username}, email: {username}{mailbox_suffix}")
            else:
                logger.info(f"更新用户信息成功 - username: {username}")
        except Exception as e:
            logger.error(f"创建/更新用户失败 - username: {username}, 错误: {str(e)}")
            return ErrorResponse(msg="用户创建失败，请稍后再试")

        # 设置部门
        if not user.dept:
            user.dept_id = 1
            logger.info(f"设置用户默认部门 - username: {username}, dept_id: 1")

        # 分配角色
        try:
            roles = Role.objects.filter(id__in=default_role_ids)
            user.role.add(*roles)
            logger.info(f"分配用户角色成功 - username: {username}, role_ids: {default_role_ids}")
        except Exception as e:
            logger.error(f"分配角色失败 - username: {username}, 错误: {str(e)}")

        # 生成JWT token
        try:
            refresh = RefreshToken.for_user(user)
            cache.set(f"user_{user.id}", "online", 60 * 5)
            access_token = str(refresh.access_token)
            logger.info(f"生成JWT token成功 - username: {username}, user_id: {user.id}")
        except Exception as e:
            logger.error(f"生成JWT token失败 - username: {username}, 错误: {str(e)}")
            return ErrorResponse(msg="token生成失败，请稍后再试")

        # 构建返回数据
        data = {
            "access": access_token,
            "refresh": str(refresh),
            "name": user.name,
            "skin": user.skin,
            "userId": user.id,
            "pwd_defaulted": user.pwd_defaulted,
            "is_staff": user.is_staff,
            "avatar": user.avatar,
            "user_type": user.user_type,
            "role_info": user.role.values("id", "name", "key"),
        }
        user.last_token = access_token
        user.save()

        # 记录登录日志
        try:
            save_login_log(request=request, login_type=1, current_user=user)
            logger.info(f"保存登录日志成功 - username: {username}, user_id: {user.id}")
        except Exception as e:
            logger.error(f"保存登录日志失败 - username: {username}, 错误: {str(e)}")

        logger.info(f"登录流程完成 - username: {username}, user_id: {user.id}")
        return DetailResponse(data)
