from django.core.paginator import Paginator
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework import status
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from django.db.models import Q
from time import sleep
import json
from drf_spectacular.utils import (
    extend_schema,
    extend_schema_view,
    OpenApiParameter,
    OpenApiExample,
)
from rest_framework import serializers
from rest_framework.pagination import LimitOffsetPagination

from .models import ProductModel, ProductChatModel
from utils.pagination import StructurePagination
import openai
from django.conf import settings

ASSISTANT_ID = 'asst_1wOnCKncEHkOfp0FjOIz4Xkp'


# Serializer for the `new_message` field in POST requests
class NewMessageSerializer(serializers.Serializer):
    new_message = serializers.CharField(
        required=True,
        help_text="The message content to send to the chat."
    )


# Custom Pagination Class
class StructurePagination(LimitOffsetPagination):
    default_limit = 10
    max_limit = 100


# Documentation for the ProductChatView
@extend_schema_view(
    get=extend_schema(
        summary="Retrieve messages for a product chat",
        parameters=[
            OpenApiParameter(
                name="limit",
                description="Number of results to return per page.",
                required=False,
                type=int,
                default=10,
            ),
            OpenApiParameter(
                name="offset",
                description="The starting position of the results.",
                required=False,
                type=int,
                default=0,
            ),
        ],
        responses={
            200: OpenApiExample(
                "Chat messages retrieved",
                value={
                    "messages": [
                        {"sender": "user", "content": "Hello!"},
                        {"sender": "assistant", "content": "How can I help you?"}
                    ]
                }
            ),
        },
    ),
    post=extend_schema(
        summary="Send a new message in the product chat",
        request=NewMessageSerializer,
                parameters=[
            OpenApiParameter(
                name="limit",
                description="Number of results to return per page.",
                required=False,
                type=int,
                default=10,
            ),
            OpenApiParameter(
                name="offset",
                description="The starting position of the results.",
                required=False,
                type=int,
                default=0,
            ),
        ],
        responses={
            200: OpenApiExample(
                "Message sent successfully",
                value={
                    "messages": [
                        {"sender": "user", "content": "Hello!"},
                        {"sender": "assistant", "content": "How can I help you?"}
                    ]
                }
            ),
            400: OpenApiExample(
                "Error example",
                value={"detail": "پیام جدید نمی‌تواند خالی باشد"},
            ),
        },
    ),
)
class ProductChatView(APIView):
    permission_classes = [IsAuthenticated]
    pagination_class = StructurePagination

    def get(self, request, pk):
        """
        Retrieve all messages for a product chat.
        """
        user = request.user
        product = get_object_or_404(ProductModel, id=pk)
        chat, created = ProductChatModel.objects.get_or_create(user=user, product=product)

        client = openai.OpenAI(api_key=settings.OPENAI_API_KEY)
        message_response = client.beta.threads.messages.list(thread_id=chat.thread)

        # Format messages
        formatted_messages = []
        for message in message_response.data:
            for content in message.content:
                if content.type == "text" and 'this is the start of the chat greet the user this chat is about the product with given detail:' not in content.text.value:
                    sender = 'user' if message.role == 'user' else 'ai'
                    formatted_messages.append({'sender': sender, 'content': content.text.value})

        # Paginate results
        paginator = StructurePagination()
        paginated_messages = paginator.paginate_queryset(formatted_messages, request)
        return paginator.get_paginated_response(paginated_messages)

    def post(self, request, pk):
        """
        Send a new message in the product chat.
        """
        user = request.user
        product = get_object_or_404(ProductModel, id=pk)
        chat, created = ProductChatModel.objects.get_or_create(user=user, product=product)

        if created:
            return Response({'detail': 'چت این کاربر با این محصول هنوز ساخته نشده'}, status=status.HTTP_400_BAD_REQUEST)

        new_message = request.data.get('new_message', '').strip()
        if not new_message:
            return Response({'detail': 'پیام جدید نمی‌تواند خالی باشد'}, status=status.HTTP_400_BAD_REQUEST)

        client = openai.OpenAI(api_key=settings.OPENAI_API_KEY)
        
        # Send the user message
        client.beta.threads.messages.create(
            thread_id=chat.thread,
            role="user",
            content=new_message
        )

        # Start the assistant's run
        run = client.beta.threads.runs.create(thread_id=chat.thread, assistant_id=ASSISTANT_ID)
        while run.status != "completed":
            run = client.beta.threads.runs.retrieve(thread_id=chat.thread, run_id=run.id)
            sleep(1)

        # Fetch the updated messages
        message_response = client.beta.threads.messages.list(thread_id=chat.thread)
        formatted_messages = []
        for message in message_response.data:
            for content in message.content:
                if content.type == "text" and 'this is the start of the chat greet the user this chat is about the product with given detail:' not in content.text.value:
                    sender = 'user' if message.role == 'user' else 'ai'
                    formatted_messages.append({'sender': sender, 'content': content.text.value})

        paginator = StructurePagination()
        paginated_messages = paginator.paginate_queryset(formatted_messages, request)
        return paginator.get_paginated_response(paginated_messages)