#!/usr/bin/env python
# @Project ：django_base_ai
# @File    : im_chat_question.py
# @Author  : cx
# @Time    : 11/2/2025
# @Desc    : 热门问题
import asyncio
import datetime
import json
import logging

import django_filters
from django.http import StreamingHttpResponse
from rest_framework import serializers
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny, IsAuthenticated

from django_base_ai.system.models import AIDeskAppManage, IMChatQA, IMChatQuestion, IMChatQuestionGroup
from django_base_ai.utils.json_request import ExecuteJsonRequest
from django_base_ai.utils.json_response import DetailResponse, ErrorResponse
from django_base_ai.utils.serializers import CustomModelSerializer
from django_base_ai.utils.viewset import CustomModelViewSet

logger = logging.getLogger(__name__)


class IMChatQuestionSerializer(CustomModelSerializer):
    sub_title = serializers.SerializerMethodField(read_only=True)

    def get_sub_title(self, obj):
        result_sub_title = []
        im_chat_question = IMChatQuestion.objects.filter(parent=obj)
        for item in im_chat_question:
            result_sub_title.append({"nid": item.id, "title": item.title, "is_enable": item.is_enable, "hit": item.hit})
        return result_sub_title

    class Meta:
        model = IMChatQuestion
        fields = "__all__"
        read_only_fields = ["id"]


class IMChatQuestionCreateUpdateSerializer(CustomModelSerializer):
    def save(self, **kwargs):
        instance = super().save(**kwargs)
        sub_title = self.initial_data.get("sub_title", [])
        for item in sub_title:
            IMChatQuestion.objects.update_or_create(
                defaults={
                    "im_chat_question_group": instance.im_chat_question_group,
                    "parent": instance,
                    "title": item.get("title", ""),
                },
                id=item.get("nid", None),
            )
        return instance

    class Meta:
        model = IMChatQuestion
        fields = "__all__"
        read_only_fields = ["id"]


class FilterIMChatQuestion(django_filters.rest_framework.FilterSet):
    im_chat_question_group = django_filters.CharFilter(field_name="im_chat_question_group")
    title = django_filters.CharFilter(field_name="title", lookup_expr="icontains")
    content = django_filters.CharFilter(field_name="content", lookup_expr="icontains")
    is_enable = django_filters.BooleanFilter(field_name="is_enable")

    class Meta:
        model = IMChatQuestion
        fields = ["im_chat_question_group", "title", "content", "is_enable"]


async def event_stream(chats):
    await asyncio.sleep(2)
    yield f"data: {json.dumps(chats)}\n\n"


class IMChatQuestionViewSet(CustomModelViewSet):
    """
    员工服务的热门问题
    list:查询
    create:新增
    update:修改
    retrieve:单例
    destroy:删除
    """

    queryset = IMChatQuestion.objects.all().filter(parent=None).order_by("hit")
    serializer_class = IMChatQuestionSerializer
    filter_class = FilterIMChatQuestion
    create_serializer_class = IMChatQuestionCreateUpdateSerializer
    update_serializer_class = IMChatQuestionCreateUpdateSerializer
    # extra_filter_backends = []

    @action(methods=["GET"], detail=False, permission_classes=[IsAuthenticated])
    def top_question(self, request, *args, **kwargs):
        nid = request.GET.get("nid", 0)
        if not nid:
            return ErrorResponse(msg="参数错误")
        question_group_result_ids = IMChatQuestionGroup.objects.filter(ai_desk_app_manage__id=nid).values_list(
            "id", flat=True
        )
        result = IMChatQuestion.objects.filter(
            im_chat_question_group__in=question_group_result_ids, parent=None
        ).values("id", "title", "content")[0:8]
        return DetailResponse(data=result, msg="获取成功")

    # QA 问答
    @action(methods=["POST"], detail=False, permission_classes=[IsAuthenticated])
    def qa_chat(self, request, *args, **kwargs):
        # 1.热门问题 QA
        # 2.AI
        # 3.人工
        current_user = request.user
        text = request.data.get("text", None)
        nid = request.data.get("nid", None)
        if not text and not nid:
            return ErrorResponse(msg="参数错误")
        ai_desk_app_manage = AIDeskAppManage.objects.filter(id=nid).first()
        if not ai_desk_app_manage:
            return ErrorResponse(msg="不存在或您无权限访问")
        im_chat_question = IMChatQuestion.objects.filter(title__contains=text).first()
        chats = {}  # 默认使用热门问题
        # 获取父级
        im_chat_question = im_chat_question.parent if im_chat_question and im_chat_question.parent else im_chat_question
        if im_chat_question:
            im_chat_question.hit += 1
            im_chat_question.save()
            chats.update({"q_type": 0, "answer": im_chat_question.content})
        elif ai_desk_app_manage.ai_switch:
            # 解析调用ai的json字符串--需要更具不同的AI接口返回进行解析，例如返回 msg,text,content等 还需要注意EventSource
            send_request = ExecuteJsonRequest()
            flag, resp_result, status_code, run_tiem = send_request.request(ai_desk_app_manage.ai_settings_json)
            print(flag, resp_result, status_code, run_tiem)
            answer = json.loads(resp_result).get("msg", "") if flag else "发生错误请稍后再试"
            chats.update({"q_type": 1, "answer": answer})
        else:
            # 未知
            answer = "您的问题我们已收到,我们会尽快回复您"
            chats.update({"q_type": 2, "answer": answer})
        # 统一记录表Q A
        im_chat_qa = IMChatQA.objects.create(
            ai_desk_app_manage=ai_desk_app_manage,
            question=text,
            answer=chats.get("answer", ""),
            q_type=chats.get("q_type", 0),
            creator=current_user.id,
            modifier=current_user.id,
        )
        chats.update({"nid": im_chat_qa.id, "is_end": True})
        return StreamingHttpResponse(event_stream(chats), content_type="text/event-stream")

    @action(methods=["GET", "POST"], detail=False, permission_classes=[AllowAny], authentication_classes=[])
    def ai_test(self, request, *args, **kwargs):
        """
        AI 接口挡板测试
        """
        print(request.data)
        print(request.query_params)
        return DetailResponse(msg=f"AI答案:{datetime.datetime.now()}")
