"""
智能体模块视图 - App端
"""
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from drf_spectacular.utils import extend_schema

from utils.response import success, error
from utils.exceptions import ErrorCode
from apps.admins.authentication import AppJWTAuthentication
from apps.devices.models import UserDevice
from .models import Spirit
from .serializers import (
    SpiritSerializer,
    SpiritListSerializer,
    CreateSpiritSerializer,
)


@extend_schema(tags=['智能体'])
class SpiritViewSet(viewsets.ModelViewSet):
    """智能体视图集（App端）"""
    
    authentication_classes = [AppJWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        return Spirit.objects.filter(user=self.request.user)
    
    def get_serializer_class(self):
        if self.action == 'list':
            return SpiritListSerializer
        if self.action == 'create':
            return CreateSpiritSerializer
        return SpiritSerializer
    
    def list(self, request, *args, **kwargs):
        """
        获取我的智能体列表
        GET /api/v1/spirits
        """
        queryset = self.get_queryset()
        serializer = SpiritListSerializer(queryset, many=True)
        return success(data=serializer.data)
    
    def create(self, request, *args, **kwargs):
        """
        创建智能体
        POST /api/v1/spirits
        """
        serializer = CreateSpiritSerializer(data=request.data)
        if serializer.is_valid():
            spirit = serializer.save(user=request.user)
            return success(data=SpiritSerializer(spirit).data, message='创建成功')
        return error(message=str(serializer.errors))
    
    def retrieve(self, request, *args, **kwargs):
        """
        获取智能体详情
        GET /api/v1/spirits/{id}
        """
        try:
            instance = self.get_object()
            serializer = SpiritSerializer(instance)
            return success(data=serializer.data)
        except Spirit.DoesNotExist:
            return error(code=ErrorCode.SPIRIT_NOT_FOUND, message='智能体不存在')
    
    def update(self, request, *args, **kwargs):
        """
        更新智能体
        PUT /api/v1/spirits/{id}
        """
        instance = self.get_object()
        serializer = SpiritSerializer(instance, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return success(data=serializer.data, message='更新成功')
        return error(message=str(serializer.errors))
    
    def destroy(self, request, *args, **kwargs):
        """
        删除智能体
        DELETE /api/v1/spirits/{id}
        """
        instance = self.get_object()
        instance.delete()
        return success(message='删除成功')

    @action(detail=True, methods=['post'])
    def unbind(self, request, pk=None):
        """
        解绑智能体（从所有设备上移除）
        POST /api/v1/spirits/{id}/unbind/
        """
        try:
            spirit = Spirit.objects.get(id=pk, user=request.user)
        except Spirit.DoesNotExist:
            return error(code=ErrorCode.SPIRIT_NOT_FOUND, message='智能体不存在')

        # 解除所有设备与该智能体的绑定
        count = UserDevice.objects.filter(
            user=request.user, spirit=spirit, is_active=True
        ).update(spirit=None)

        return success(message=f'已解绑智能体，数据已保留在云端（影响 {count} 个设备）')

    @action(detail=True, methods=['get'], url_path='owner-info')
    def owner_info(self, request, pk=None):
        """
        获取智能体所有者信息
        GET /api/v1/spirits/{id}/owner-info/

        Bug #45 fix: spirit.user (owner) may be None if the user record was
        removed outside of the normal cascade path; guard with an explicit
        None-check instead of accessing .nickname unconditionally.
        """
        try:
            spirit = Spirit.objects.get(id=pk, user=request.user)
        except Spirit.DoesNotExist:
            return error(code=ErrorCode.SPIRIT_NOT_FOUND, message='智能体不存在')

        # Bug #45 fix: null-safe access – avoid TypeError when owner is None
        owner_name = spirit.user.nickname if spirit.user else None
        return success(data={'owner_name': owner_name})

    @action(detail=True, methods=['post'])
    def inject(self, request, pk=None):
        """
        注入智能体到设备
        POST /api/v1/spirits/{id}/inject/
        """
        try:
            spirit = Spirit.objects.get(id=pk, user=request.user)
        except Spirit.DoesNotExist:
            return error(code=ErrorCode.SPIRIT_NOT_FOUND, message='智能体不存在')

        user_device_id = request.data.get('user_device_id')
        if not user_device_id:
            return error(message='请指定设备')

        try:
            user_device = UserDevice.objects.get(
                id=user_device_id, user=request.user, is_active=True
            )
        except UserDevice.DoesNotExist:
            return error(code=ErrorCode.DEVICE_NOT_FOUND, message='设备绑定记录不存在')

        user_device.spirit = spirit
        user_device.save(update_fields=['spirit'])

        return success(message='智能体注入成功')
