"""
企业微信 API

供外部企业微信服务端程序调用：
1. 绑定接口：将企业微信 user_id 与本系统 Employee 绑定
2. 登录接口：通过已绑定的 wecom_user_id 快捷获取 JWT token

认证方式：AGENT_ACCESS_KEY（通过 Authorization 头传入）。
"""

import logging

from django.contrib.auth import authenticate
from rest_framework import serializers, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken

from api_v2.views.ai import AgentAccessKeyAuthentication
from basic_info.models import Employee

logger = logging.getLogger(__name__)


class WecomBindingRequestSerializer(serializers.Serializer):
    wecom_user_id = serializers.CharField(
        max_length=128,
        help_text='企业微信 OAuth2 返回的 user_id',
    )
    username = serializers.CharField(
        max_length=150,
        help_text='本系统用户名',
    )
    password = serializers.CharField(
        max_length=128,
        help_text='本系统用户密码',
    )
    force_update = serializers.BooleanField(
        default=False,
        required=False,
        help_text='如果该 Employee 已绑定其他企业微信用户，是否强制覆盖',
    )


class WecomBindingView(APIView):
    """
    企业微信用户绑定接口。

    POST /api/v2/wecom/binduser/

    请求体：
    - wecom_user_id: 企业微信用户 ID
    - username: 本系统用户名
    - password: 本系统用户密码
    - force_update: (可选) 是否强制覆盖已有绑定，默认 false

    认证：Authorization 头传入 AGENT_ACCESS_KEY
    """

    authentication_classes = [AgentAccessKeyAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request):
        ser = WecomBindingRequestSerializer(data=request.data)
        ser.is_valid(raise_exception=True)

        wecom_user_id = ser.validated_data['wecom_user_id']
        username = ser.validated_data['username']
        password = ser.validated_data['password']
        force_update = ser.validated_data.get('force_update', False)

        # 1. 验证本系统用户凭据
        user = authenticate(username=username, password=password)
        if user is None:
            return Response(
                {'error': '用户名或密码错误'},
                status=status.HTTP_401_UNAUTHORIZED,
            )

        if not user.is_active:
            return Response(
                {'error': '该用户已被禁用'},
                status=status.HTTP_403_FORBIDDEN,
            )

        # 2. 查找关联的 Employee
        employee = Employee.objects.filter(sys_user=user).first()
        if employee is None:
            return Response(
                {'error': '该用户未关联任何员工记录'},
                status=status.HTTP_404_NOT_FOUND,
            )

        # 3. 检查该 wecom_user_id 是否已被其他 Employee 绑定
        existing = Employee.objects.filter(wecom_user_id=wecom_user_id).exclude(id=employee.id).first()
        if existing is not None:
            return Response(
                {'error': f'该企业微信用户已绑定到其他员工: {existing.name} (ID: {existing.id})'},
                status=status.HTTP_409_CONFLICT,
            )

        # 4. 检查该 Employee 是否已有不同的 wecom_user_id
        if employee.wecom_user_id and employee.wecom_user_id != wecom_user_id:
            if not force_update:
                return Response(
                    {
                        'error': '该员工已绑定其他企业微信用户',
                        'current_wecom_user_id': employee.wecom_user_id,
                        'hint': '如需覆盖，请传入 force_update=true',
                    },
                    status=status.HTTP_409_CONFLICT,
                )

        # 5. 执行绑定
        employee.wecom_user_id = wecom_user_id
        employee.save(update_fields=['wecom_user_id', 'updated_at'])

        logger.info(
            'WeChat Work binding success: wecom_user_id=%s -> employee=%s (ID: %s)',
            wecom_user_id,
            employee.name,
            employee.id,
        )

        return Response(
            {
                'message': '绑定成功',
                'employee_id': employee.id,
                'employee_name': employee.name,
                'wecom_user_id': wecom_user_id,
            },
            status=status.HTTP_200_OK,
        )


class WecomLoginRequestSerializer(serializers.Serializer):
    wecom_user_id = serializers.CharField(
        max_length=128,
        help_text='企业微信 OAuth2 返回的 user_id',
    )


class WecomLoginView(APIView):
    """
    企业微信快捷登录接口。

    POST /api/v2/wecom/login/

    通过已绑定的 wecom_user_id 获取本系统的 JWT token，
    无需再次输入用户名密码。

    请求体：
    - wecom_user_id: 企业微信用户 ID（必须已通过绑定接口完成绑定）

    认证：Authorization 头传入 AGENT_ACCESS_KEY
    """

    authentication_classes = [AgentAccessKeyAuthentication]
    permission_classes = [IsAuthenticated]

    def post(self, request):
        ser = WecomLoginRequestSerializer(data=request.data)
        ser.is_valid(raise_exception=True)

        wecom_user_id = ser.validated_data['wecom_user_id']

        # 1. 通过 wecom_user_id 查找 Employee
        employee = Employee.objects.select_related('sys_user').filter(
            wecom_user_id=wecom_user_id,
        ).first()

        if employee is None:
            return Response(
                {'error': '该企业微信用户未绑定本系统员工'},
                status=status.HTTP_404_NOT_FOUND,
            )

        # 2. 检查关联的系统用户
        user = employee.sys_user
        if user is None:
            return Response(
                {'error': '该员工未关联系统用户'},
                status=status.HTTP_404_NOT_FOUND,
            )

        if not user.is_active:
            return Response(
                {'error': '该用户已被禁用'},
                status=status.HTTP_403_FORBIDDEN,
            )

        # 3. 生成 JWT token
        refresh = RefreshToken.for_user(user)

        logger.info(
            'WeChat Work login success: wecom_user_id=%s -> user=%s (employee=%s)',
            wecom_user_id,
            user.username,
            employee.name,
        )

        return Response(
            {
                'access': str(refresh.access_token),
                'refresh': str(refresh),
                'employee_id': employee.id,
                'employee_name': employee.name,
                'username': user.username,
            },
            status=status.HTTP_200_OK,
        )
