import datetime
import random
import string

import requests
from django.db.models import Q, Count
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import api_view, permission_classes
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from authentication.models import SystemUserProfile, Group
from authentication.sms_management import ticket_answered
from helper_eata import token, chat_id
from panel.filterset import TicketsFilterSet
from panel.helper import build_query
from ticket.models import TicketSupport, MessageSupport, TicketPermission, TicketClosePermission
from ticket.serializers import TicketSupportSerializer, MessageSupportSerializer, TicketPermissionSerializer, \
    SystemUserProfileForTicketPermissionSerializer, MessageSupportWithoutReadBySerializer, \
    TicketClosePermissionSerializer
from .bucket import upload_to_liara
from .helper import send_image_to_server


class CustomPagination(PageNumberPagination):
    page_size = 10


def update_unread_ticket(tickets, user):
    user_roles = list(user.role.all())

    unread_ticket_ids = MessageSupport.objects.filter(
        Q(ticket__user=user) |
        Q(ticket__to_user=user) |
        Q(ticket__to_role__in=user_roles) |
        Q(ticket__referred_by=user) |
        Q(ticket__referred_to=user.id),
        ~Q(created_by=user),
        ~Q(read_by=user.id),
        ticket__in=tickets
    ).values_list('ticket_id', flat=True).distinct()

    unread_set = set(unread_ticket_ids)

    for ticket in tickets:
        ticket.unread_message = ticket.id in unread_set

    TicketSupport.objects.bulk_update(tickets, ['unread_message'])


class TicketSupportViewSet(viewsets.ModelViewSet):
    queryset = TicketSupport.objects.filter(trash=False).select_related(
        'user', 'referred_by'
    ).prefetch_related(
        'to_role', 'referred_to', 'to_user').order_by('-unread_message', '-create_date')
    serializer_class = TicketSupportSerializer
    permission_classes = [TokenHasReadWriteScope]
    pagination_class = CustomPagination
    filterset_class = TicketsFilterSet

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        role_list = list(user.role.values_list('id', flat=True).distinct())
        role_check = any(role in ['AdminX', 'SuperAdmin'] for role in user.role.values_list('name', flat=True))
        type_param = request.GET.get('type', None)
        status = request.GET.get('status', 'open')
        base_filter = Q(user=user) | Q(to_user=user.id) | Q(to_role__in=role_list) | Q(referred_to=user.id) | Q(
            referred_by=user)

        if role_check:
            if type_param:
                query = self.queryset.filter(type_ticket=type_param,
                                             status=status).distinct() if type_param else self.queryset
            else:
                query = self.queryset.filter(status=status).distinct()

        else:
            if type_param:
                query = self.queryset.filter(base_filter, type_ticket=type_param, status=status).distinct()
            else:
                query = self.queryset.filter(base_filter, status=status)

        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                query = query.filter(
                    build_query(self.filterset_class, value)
                )
        update_unread_ticket(query, user)
        query = query.order_by('-unread_message', '-create_date')
        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)
        page = self.paginate_queryset(query)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        ser_data = self.serializer_class(query, many=True)
        return Response(ser_data.data, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        type_ticket = request.data.get('type_ticket')
        read_only = request.data.get('read_only')
        to_user_data = request.data.get('to_user')
        if request.data.get('image') is not None:
            image = send_image_to_server(request.data['image'])
        else:
            image = None
        if request.FILES.get('file'):
            file_obj = request.FILES.get('file')
            file_url = upload_to_liara(file_obj, file_obj.name)
        else:
            file_url = None
        if to_user_data:
            to_users = SystemUserProfile.objects.filter(key__in=request.data['to_user'])
            ticket = TicketSupport(
                user=user,
                title=request.data['title'],
                status='open',
                read_only=read_only,
                type_ticket=type_ticket,
                role=request.data.get('role'),
            )
            ticket.save()
            ticket.to_user.set(to_users)

        else:
            to_role = Group.objects.filter(name__in=request.data.get('to_role'))
            if ((SystemUserProfile.objects.filter(trash=False, role__in=to_role).count() < 2)):
                return Response({'result': 'برای نقش انتخابی، لطفاً تیکت شخصی ثبت کنید!'},
                                status=status.HTTP_403_FORBIDDEN)
            ticket = TicketSupport(
                user=user,
                title=request.data['title'],
                status='open',
                read_only=read_only,
                type_ticket=type_ticket,
                role=request.data.get('role'),
            )
            ticket.save()
            ticket.to_role.set(to_role)
        msg = MessageSupport(
            ticket=ticket,
            message=request.data['message'],
            created_by=user,
            sender=request.data.get('sender'),
            picture=image,
            file=file_url)
        msg.save()
        return Response({'msg': 'با موفقیت انجام شد.'}, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        ticket_id = request.data.get('ticket')
        ticket = self.queryset.filter(ticket_id=int(ticket_id)).first()

        if ticket:
            if 'referred_to' in request.data:
                referred_to = SystemUserProfile.objects.filter(key__in=request.data['referred_to'])
                ticket.referred_by = SystemUserProfile.objects.get(user=request.user)
                ticket.status = 'open'
                ticket.is_referred = True
                ticket.save()
                referrer_name = []
                for user in referred_to:
                    if not ticket.referred_to.filter(id=user.id).exists():
                        ticket.referred_to.add(user)
                        referrer_name.append(user.fullname)
                if len(referrer_name) > 1:
                    names = ' و '.join(referrer_name)
                else:
                    names = referrer_name[0] if referrer_name else ''
                if referrer_name:
                    MessageSupport.objects.create(
                        ticket=ticket,
                        message=f"تیکت شماره {ticket.ticket_id}  به ({names}) ارجاع داده شد.",
                        created_by=SystemUserProfile.objects.get(user=request.user),
                        sender='Admin'
                    )
                return Response({'message': 'تیکت با موفقیت ارجاع داده شد.'}, status=200)

            else:
                ticket.status = 'closed'
                ticket.save()
                return Response({'result': 'تیکت با موفقیت پایان یافت.'}, status=status.HTTP_200_OK)
        return Response({'result': 'تیکت وجود ندارد!'}, status=status.HTTP_400_BAD_REQUEST)


class MessageSupportViewSet(viewsets.ModelViewSet):
    queryset = MessageSupport.objects.all().select_related('ticket').order_by('created_at')
    serializer_class = MessageSupportSerializer
    permission_classes = [TokenHasReadWriteScope]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        ticket_id = request.GET.get('ticket')
        role_list = list(user.role.values_list('id', flat=True).distinct())
        role_check = any(
            role in ['AdminX', 'SuperAdmin', 'ProvinceOperator'] for role in user.role.values_list('name', flat=True))
        query = self.queryset.filter(ticket__ticket_id=int(ticket_id)).order_by('-created_at')
        if query.filter(Q(ticket__user=user) | Q(ticket__to_user=user.id) | Q(ticket__to_role__in=role_list) | Q(
                ticket__referred_by=user) | Q(ticket__referred_to=user.id)).exists():
            unseen_messages = query.filter(~Q(created_by=user), last_seen__isnull=True)
            unseen_messages.update(last_seen=datetime.datetime.now())

            for message in query.filter(~Q(created_by=user)):
                if not message.read_by.filter(id=user.id).exists():
                    message.read_by.add(user)

        query = query.defer('message')
        if role_check:
            srz_data = self.serializer_class(query, many=True).data
        else:
            srz_data = MessageSupportWithoutReadBySerializer(query, many=True).data
        return Response(srz_data)

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.select_related('user').filter(user=request.user).first()
        ticket_id = request.data.get('ticket')
        ticket = TicketSupport.objects.get(ticket_id=int(ticket_id))

        if ticket.status == 'closed':
            return Response({'result': 'این تیکت بسته شده است!'}, status=status.HTTP_403_FORBIDDEN)

        if ticket.read_only == False and ticket.type_ticket == 'public' and ticket.parent is None \
                and ticket.user != user:
            new_ticket = TicketSupport(
                user=user,
                title=ticket.title,
                status='open',
                read_only=False,
                type_ticket='single',
                parent=ticket,
                last_message=request.data.get('sender'),
                role=request.data.get('role'),
            )
            new_ticket.save()
            new_ticket.to_user.add(ticket.user)

            msg = MessageSupport(
                ticket=new_ticket,
                message=request.data.get('message'),
                created_by=user,
                sender=request.data.get('sender')
            )
        else:
            msg = MessageSupport(
                ticket=ticket,
                message=request.data.get('message'),
                created_by=user,
                sender=request.data.get('sender')
            )
            ticket.last_message = request.data.get('sender')
            ticket.save()
        if request.data['send_message'] == True:
            ticket_answered(ticket.user.mobile)
            msg.send_message = True
        if request.data.get('image') is not None:
            # ran = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15))
            # upload_object_resize(image_data=request.data['image'], bucket_name="profileimagedefault",
            #                      object_name="{0}.jpg".format(str(ran)))
            msg.picture = send_image_to_server(request.data['image'])
        if request.FILES.get('file'):
            file_obj = request.FILES.get('file')
            file_url = upload_to_liara(file_obj, file_obj.name)
            msg.file = file_url
        msg.save()
        ser_data = self.serializer_class(msg)
        return Response(ser_data.data, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        msg_id = request.data.get('message_id')
        instance = self.get_queryset().get(id=msg_id)
        request.data.pop('message_id')
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({'result': "با موفقیت انجام شد."}, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class MessageForRoleViewSet(viewsets.ModelViewSet):
    queryset = MessageSupport.objects.all()
    serializer_class = MessageSupportSerializer
    permission_classes = [TokenHasReadWriteScope]

    def create(self, request, *args, **kwargs):
        user_sender = SystemUserProfile.objects.get(user=request.user)
        if 'role' in request.data.keys():
            to_user = SystemUserProfile.objects.filter(trash=False, role__name__in=request.data['role'])
            relations = [
                TicketSupport(
                    user=user_sender,
                    title=request.data['title'],
                    status='open',
                    to_user=user
                )
                for user in to_user
            ]
            TicketSupport.objects.bulk_create(relations)

        return Response({'msg': 'با موفقیت ارسال شد'}, status=status.HTTP_201_CREATED)


class TicketPermissionViewSet(viewsets.ModelViewSet):
    queryset = TicketPermission.objects.all()
    serializer_class = TicketPermissionSerializer
    permission_classes = [AllowAny]

    def create(self, request, *args, **kwargs):
        role = request.data['role']
        group = request.data['roles']
        roles = Group.objects.filter(name__in=group)
        ticket = TicketPermission.objects.get(role=role)
        ticket.roles.set(roles)
        ser_data = self.serializer_class(ticket)
        return Response(ser_data.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        if 'role' in request.GET:
            role = request.GET['role']
            query = self.queryset.get(role=role)
            ser_data = self.serializer_class(query).data
            return Response(ser_data, status=status.HTTP_200_OK)
        else:
            query = self.queryset
            ser_data = self.serializer_class(query, many=True).data
            return Response(ser_data, status=status.HTTP_200_OK)


class GetUserFromRoleViewSet(viewsets.ModelViewSet):
    queryset = SystemUserProfile.objects.all()
    serializer_class = SystemUserProfileForTicketPermissionSerializer
    permission_classes = [TokenHasReadWriteScope]

    def list(self, request, *args, **kwargs):
        role = request.GET['role']
        user = SystemUserProfile.objects.filter(~Q(user=request.user), trash=False, role__name=role, )
        ser_data = self.serializer_class(user, many=True)
        return Response(ser_data.data, status=status.HTTP_200_OK)


class TicketClosePermissionViewSet(viewsets.ModelViewSet):
    queryset = TicketClosePermission.objects.all().first()
    serializer_class = TicketClosePermissionSerializer
    permission_classes = [TokenHasReadWriteScope]


@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def get_num_message(request):
    user = SystemUserProfile.objects.get(user=request.user)
    message = MessageSupport.objects.filter(
        Q(ticket__user=user) | Q(ticket__to_user=user) | Q(ticket__to_role__in=user.role.all()) | Q(
            ticket__referred_by=user) | Q(ticket__referred_to=user.id)
        , ~Q(created_by=user)).exclude(read_by=user.id).values('ticket').annotate(
        ticket_count=Count('ticket', distinct=True)
    ).distinct()
    state = True if message.count() > 0 else False
    return Response({
        'state': state,
        'num': message.count(),
    })


# @api_view(["PUT"])
# @csrf_exempt
# @permission_classes([AllowAny])
# def FileUploadView(request):
# # queryset = TicketSupport.objects.all()
# # permission_classes = [AllowAny]
# # serializer_class = TicketSupportSerializer
# #
# # def create(self, request, *args, **kwargs):
#     file_obj = request.FILES.get('file')
#     if not file_obj:
#         return Response({"error": "فایلی ارسال نشده است"}, status=status.HTTP_400_BAD_REQUEST)
#
#     try:
#         file_url = upload_to_liara(file_obj, file_obj.name)
#         return Response({"file_url": file_url}, status=status.HTTP_201_CREATED)
#     except Exception as e:
#         return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


def bot_eitaa_for_bar():
    url = f'https://eitaayar.ir/api/{token}/sendMessage'
    data = {
        "cookie": "ASP.NET_SessionId=w1jadrzcqgznxugnjee1xrkj; .ASPXAUTH=4CC27FD1BAB0CA729584056577AA51209F731F22CDF4B95F9FEE33AD12F1DFFF960C77B0A237D5733E336195A2CA6DB1C1F2CA2EDCD079EC0B3C3092A2BF1BA8811D7C44263B1E5EB84430C0906024A55D51AF1FE5852F406C358A051715BB9270475D58228F44380D12FA075A4DF0E029220F0C809AEDDDF58FFE9568064DD9D397B038D19DC1757232A92EA63571EA7B47E1706F677528E539301417093B523B6C2BFD340AA33DC32D50E7853E3D14D93924313B9B1EB36320C90A2303BB852841EE0DE1D844B281B4CD6D7E95D593CF2E2F0C3816687C529B7702863F75CD6549F49D346C7C88F22F033C75C357BE9E91AD170A2502731BC03AE2DF09F594417646FE332B8BAB70673E584A23AD45CADC285C554B66FD29DD989F85962891A11C06FC84832DD8FB03933CF26E190601D493B0430A742544B8BC0A8639E4E5788432AA401FAFFD3A1C6793FB24909A992405D07E53B81DF546AB07ED90314735518C37E9291F10E2B723B795B8BB838C2810CE103A4EF893211BFDBB605ADBE0E3B9B35438A5FE3506937D020EC2EF061B6D1E3AAFB3A9A138CC219A4A556CEB6A2E44C18D53C85666A5C0C9663F8314EFD97FFF5C1844C0FEB4362A781E2138785D832EEFD1AEDAD1271C2513A6F4EC1174EF107AC2E9FEFF8A9A111CC6D6189CCC66E93224EE4D30813AAD9DCDE1CFC530B08CB67827C351DCE4C2AFD4E3FB12E85EA0CD6E2D3D4CC8753D74E863A37C5675D82C9977518A942786EF055F0DBFC809B9F9B6A45B269526FC9D8B5E888B1C6E40C6ACE8EB37ED7E1F9F266A018936F3228A3C8E20C1BD869CC657D1CE19FFEA8C8B979DE5077E17AE5FA1F085B3A424C91DA19D3743871A2A9440937B2C4E076EC99AE4DEE1A7AF601448F2F763FC2DF85ED8902287DDD0ED5B9E649A4490900B4BF64F639CDD761326AC08D1B540CBD853B42F556FFB8FD5BC33A54E68125CD20278B191A1896BF955FFA1B4CC5308E12A84003B64B0EE532079563DC334FB9AEB9B742803EBE35C82CA14E5D0D84CA736AB9A2E07EECFF98657561C029ECE3C1249DA843B4236E41BD745E54B1A86ED2CE4EA0FDDBB3B4B2B97A87548B23298283F6D09094F7BC709FAABE59CC84138F83B083EAB15BE0B032481; leggedOut=-"
    }
    r = requests.post(url='https://pay.rasadyar.net/transporting-chickens/', data=data)

    data = {
        'chat_id': chat_id,
        'text': r.status_code,
    }
    response = requests.post(url, data=data, verify=False)

    return HttpResponse(response.status_code)


# def close_ticket_cron_job():
#     ticket=TicketSupport.objects.filter(Q(unread_message=False,read_only=True)|Q(unread_message=True,read_only=False),trash=False,status='open')
#     for t in ticket:
#         two_day_ago =datetime.datetime.now().date() - datetime.timedelta(days=2)
#         if (t.create_date.date() - datetime.datetime.now().date()).days > 2:
#             t.status='closed'
#             t.to_role=None
#             t.title=None
#             t.trash=False
#             t.create_date=datetime.datetime.now()
#             t.save()
#         else:
#             continue

@api_view(["GET"])
@csrf_exempt
@permission_classes([AllowAny])
def closed_unread_ticket(request):
    user = SystemUserProfile.objects.filter(trash=False, role__name='AdminX').first()
    two_day_ago = datetime.datetime.now() - datetime.timedelta(days=2)
    ten_day_ago = datetime.datetime.now() - datetime.timedelta(days=10)
    tickets = TicketSupport.objects.filter(
        trash=False,
        status='open',
        type_ticket='single'
    )
    text_two_day_ago_message = 'به دلیل عدم دریافت پیام جدید در مدت 48 ساعت، این تیکت توسط سامانه به صورت خودکار بسته شد.'
    text_ten_day_ago_message = 'به دلیل خوانده نشدن پیام در مدت 10 روز، این تیکت توسط سامانه به صورت خودکار بسته شد.'
    for ticket in tickets:
        message = MessageSupport.objects.filter(ticket=ticket).last()
        if not message:
            continue
        if message.read_by.exists() and message.last_seen.date() <= two_day_ago.date():
            msg = MessageSupport(
                ticket=ticket,
                message=text_two_day_ago_message,
                created_by=user)
            msg.save()
            ticket.status = 'closed'
            ticket.save()

        if not message.read_by.exists() and message.created_at.date() <= ten_day_ago.date():
            msg = MessageSupport(
                ticket=ticket,
                message=text_ten_day_ago_message,
                created_by=user)
            msg.save()
            ticket.status = 'closed'
            ticket.save()

    return HttpResponse('ok')


def closed_unread_ticket_cron():
    user = SystemUserProfile.objects.filter(trash=False, role__name='AdminX').first()
    two_day_ago = datetime.datetime.now() - datetime.timedelta(days=2)
    ten_day_ago = datetime.datetime.now() - datetime.timedelta(days=10)
    tickets = TicketSupport.objects.filter(
        trash=False,
        status='open',
        type_ticket='single'
    )
    text_two_day_ago_message = 'به دلیل عدم دریافت پیام جدید در مدت 48 ساعت، این تیکت توسط سامانه به صورت خودکار بسته شد.'
    # text_ten_day_ago_message = 'به دلیل خوانده نشدن پیام در مدت 10 روز، این تیکت توسط سامانه به صورت خودکار بسته شد.'
    for ticket in tickets:
        message = MessageSupport.objects.filter(ticket=ticket).last()
        if not message:
            continue
        if message.read_by.exists() and message.last_seen.date() <= two_day_ago.date():
            msg = MessageSupport(
                ticket=ticket,
                message=text_two_day_ago_message,
                created_by=user)
            msg.save()
            ticket.status = 'closed'
            ticket.save()

        # if not message.read_by.exists() and message.created_at.date() <= ten_day_ago.date():
        #     msg = MessageSupport(
        #         ticket=ticket,
        #         message=text_ten_day_ago_message,
        #         created_by=user)
        #     msg.save()
        #     ticket.status = 'closed'
        #     ticket.save()


@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def get_unread_ticket_for_dashboard(request):
    user = SystemUserProfile.objects.get(user=request.user)
    role_list = list(user.role.values_list('id', flat=True).distinct())
    base_filter = Q(user=user) | Q(to_user=user.id) | Q(to_role__in=role_list) | Q(referred_to=user.id) | Q(
        referred_by=user)
    query = TicketSupport.objects.filter(base_filter, status='open',trash=False).select_related(
        'user', 'referred_by'
    ).prefetch_related(
        'to_role', 'referred_to', 'to_user').order_by('-create_date')
    update_unread_ticket(query, user)
    query1 = query.filter(unread_message=True)
    ser_data = TicketSupportSerializer(query1, many=True)
    return Response(ser_data.data, status=status.HTTP_200_OK)