from .models import *
from django.db.models import Q, Value as V, Count, OuterRef, Subquery
from django.http import HttpResponse, Http404, JsonResponse
from django.template import loader, RequestContext
from django.contrib.auth.decorators import login_required
from BaseModels.mailSender import techSendMail
from django.utils.translation import gettext as _
from datetime import datetime
from django.template.loader import render_to_string
from django.urls import reverse
import json
from datetime import datetime, time
from django.conf import settings



def get_unanswered_msgs_count_for_user(user):
    msgs = Message.objects.filter(receiver=user, status='sended', group=None)
    return msgs.count()



def get_update_chat_Dict(data):
    from AuthApp.models import User

    res_Dict = {}
    msgs = []
    Dict = {}
    context_Dict = {}

    last_message_modifiedDT = None

    required_beep = False

    required_full_support_chat_html = False

    try:

        if type(data) == str:
            data = json.loads(data)
        ticket = None

        tpl_name = 'blocks/profile/b_messages_container.html'

        if 'ticket_id' in data and data['ticket_id'] and data['ticket_id'] != 'null':
            ticket = MsgGroup.objects.get(id=data['ticket_id'])
            res_Dict.update({'ticket': ticket.id})

        sender = User.objects.get(id=data['sender'])
        receiver = None
        if 'receiver' in data and data['receiver']:
            receiver = User.objects.get(id=data['receiver'])

        if data['sender'] == data['cur_user']:
            context_Dict.update({'user': sender})
        else:
            context_Dict.update({'user': receiver})

        context_Dict.update({'cur_receiver': receiver})

        required_beep = data['required_beep']


        if not ticket:

            if data['receiver'] == data['cur_user']:
                # получаем правую панель с получателями
                # получатели
                receivers, unread_msgs_count = get_chat_receivers_for_user(receiver)


                # формируем правую панель
                context_Dict.update({
                    'receivers': receivers,
                    'MEDIA_URL': settings.MEDIA_URL
                })
                users_list_html = render_to_string(
                    'blocks/profile/b_list_of_users_messenger.html', context_Dict)
                res_Dict.update({
                    'users_list_html': users_list_html,
                    'unread_msgs_count': unread_msgs_count
                })

            msgs = get_msgs_for_chat_w_users(sender, receiver)

        if ticket:
            msgs = get_messages_for_ticket(ticket)
            # если меньше 3 сообщений значит выведена не полная форма - требуется другой шаблон
            if len(msgs) < 3 and data['receiver'] == data['cur_user']:
                tpl_name = 'blocks/profile/b_support_chat.html'
                required_full_support_chat_html = True
            elif 'bad_manager' in data:
                tpl_name = 'blocks/profile/b_support_chat.html'
                required_full_support_chat_html = True

            context_Dict.update({'ticket': ticket})
            if ticket.manager:
                context_Dict.update({'new_msg_allow': True})

        context_Dict.update({
            'messages': msgs,
            'MEDIA_URL': settings.MEDIA_URL
        })
        html = render_to_string(tpl_name, context_Dict)
        if required_full_support_chat_html:
            res_Dict.update({'support_chat_html': html})
        else:
            res_Dict.update({'chat_html': html})


        res_Dict.update({
            'required_beep': required_beep,
        })
        return res_Dict

    except Exception as e:
        msg = f'update_chat_ajax2 Error = {str(e)}'
        return {'error': msg}


def send_msg(data):
    from AuthApp.models import User
    import base64
    import os

    res_Dict = {}
    msg = None
    required_update_tickets_list_wo_managers = False

    try:
        if type(data) == str:
            data = json.loads(data)

        ticket = None

        tpl_name = 'blocks/profile/b_messages_container.html'

        if 'text' in data or 'files' in data:

            if 'ticket_id' in data:
                ticket = MsgGroup.objects.get(id=data['ticket_id'])

            sender = User.objects.get(id=data['sender'])
            receiver = User.objects.get(id=data['receiver'])

            msg_create_kwargs = {}

            # если только что манагер присоединился к тикету
            if ticket:
                required_update_tickets_list_wo_managers = True
                if not ticket.manager:
                    if sender.is_staff:
                        ticket.manager = sender
                    else:
                        ticket.manager = receiver

                    ticket.save()

                    # создаем сообщение на базе темы и сообщения введенных пользователем при создании тикета
                    kwargs = {
                        'sender': ticket.owner,
                        'receiver': ticket.manager,
                        'text': ticket.text,
                        'group': ticket,
                    }

                    msg = Message.objects.create(**kwargs)
                    Message.objects.filter(id=msg.id).update(modifiedDT=ticket.createDT, createDT=ticket.createDT)
                    # ------------------------

                else:
                    if not sender in (ticket.owner, ticket.manager) or not receiver in (ticket.owner, ticket.manager):
                        return {
                            'msg': None,
                            'required_update_tickets_list_wo_managers': required_update_tickets_list_wo_managers
                        }

                res_Dict.update({
                    'ticket': ticket,
                })

                msg_create_kwargs.update({
                    'group': ticket,
                })

                res_Dict.update(get_ticketsDict_for_staff(sender))

            # if not msg:
            msg_create_kwargs.update({
                'sender': sender,
                'receiver': receiver,
            })

            if 'text' in data:
                msg_create_kwargs.update({'text': data['text']})

            msg = Message.objects.create(**msg_create_kwargs)

            if 'files' in data:
                files_list = []
                for file in data['files']:
                    file_data =json.loads(file)

                    if not os.path.exists(f'chat_file_storage/{msg.id}'):
                        os.makedirs(f'chat_file_storage/{msg.id}')
                    f = open(f'chat_file_storage/{msg.id}/{file_data["file_name"]}', 'wb+')
                    head, content = file_data['file'].split(',')
                    content = base64.b64decode(content)
                    f.write(content)
                    f.close()

                    del file_data['file']
                    files_list.append(file_data)
                msg.files = files_list
                msg.save(update_fields=['files'])



        #     if ticket:
        #         msgs = get_messages_for_ticket(ticket)
        #     else:
        #         msgs = get_msgs_for_chat_w_users(sender, receiver)
        #
        #     receivers, unread_msgs_count = get_chat_receivers_for_user(sender)
        #
        #     res_Dict.update({
        #         'messages': msgs,
        #         'cur_receiver': receiver,
        #         'receivers': receivers,
        #         'text': data['text'],
        #         'modifiedDT': msgs[0].modifiedDT
        #     })
        #
        # html = render_to_string(tpl_name, res_Dict)
        # return {'html': html, 'sender': data['sender']}
        return {
            'msg': msg,
            'required_update_tickets_list_wo_managers': required_update_tickets_list_wo_managers
        }

    except Exception as e:
        msg = f'send_msg_ajax Error = {str(e)}'
        print(msg)
        # return {'error': msg}
        return {
            'msg': msg,
            'required_update_tickets_list_wo_managers': required_update_tickets_list_wo_managers
        }



# def get_create_route_for_customer_page_content_Dict(request):
#     from AuthApp.models import User
#
#     msgs = []
#     try:
#         cur_receiver = User.objects.get(id=receiver_id)
#
#         msgs = get_msgs_for_chat_w_users(request.user, cur_receiver)
#         msgs.filter(receiver=request.user).update(status='seen')
#
#     except User.DoesNotExist:
#         cur_receiver = None
#
#     receivers, unread_msgs_count = get_chat_receivers_for_user(request.user)
#
#     Dict = {
#         'cur_receiver': cur_receiver,
#         'messages': msgs,
#         'receivers': receivers,
#         'page': 'chat',
#     }
#     return Dict


def get_chat_page_content_html(request, receiver_id=None):
    from AuthApp.models import User

    msgs = []
    try:
        cur_receiver = User.objects.get(id=receiver_id)

        msgs = get_msgs_for_chat_w_users(request.user, cur_receiver)
        msgs.filter(receiver=request.user).update(status='seen')

    except User.DoesNotExist:
        cur_receiver = None

    receivers, unread_msgs_count = get_chat_receivers_for_user(request.user)

    Dict = {
        'cur_receiver': cur_receiver,
        'messages': msgs,
        'receivers': receivers,
        'page': 'chat',
    }
    tpl_name = 'blocks/profile/b_chats.html'

    html = render_to_string(tpl_name, Dict, request=request)
    return html

def get_chat_page_content_Dict(request, receiver_id=None):
    from AuthApp.models import User

    msgs = []
    try:
        cur_receiver = User.objects.get(id=receiver_id)

        msgs = get_msgs_for_chat_w_users(request.user, cur_receiver)
        msgs.filter(receiver=request.user).update(status='seen')

    except User.DoesNotExist:
        cur_receiver = None

    receivers, unread_msgs_count = get_chat_receivers_for_user(request.user)

    Dict = {
        'cur_receiver': cur_receiver,
        'messages': msgs,
        'receivers': receivers,
        'page': 'chat',
    }
    return Dict


def get_msgs_for_chat_w_users(user1, user2):

    msgs = Message.objects.filter(
        Q(sender=user1) | Q(receiver=user1),
        Q(sender=user2) | Q(receiver=user2),
        group=None
    ).order_by('-modifiedDT')
    return msgs

def get_chat_receivers_for_user(user, cur_receiver=None):
    msgs = Message.objects.filter(
        Q(sender=user) | Q(receiver=user),
        group=None
    ).order_by('-modifiedDT')#.select_related('sender', 'receiver').values('sender', 'receiver').distinct()

    receivers_list = []

    unread_msgs_count = 0

    for msg in msgs:
        if msg.receiver not in receivers_list and msg.receiver != user:
            msg.receiver.unread_msgs_count = 0
            if msg.text:
                msg.receiver.last_msg = msg.text
            elif msg.files:
                msg.receiver.last_msg = msg.files[len(msg.files)-1]['file_name']
            receivers_list.append(msg.receiver)



        if msg.sender not in receivers_list and msg.sender != user:
            msg.sender.unread_msgs_count = 0
            receivers_list.append(msg.sender)
            if msg.text:
                msg.sender.last_msg = msg.text
            elif msg.files:
                msg.sender.last_msg = msg.files[len(msg.files)-1]['file_name']

            if msg.status == 'sended':
                i = receivers_list.index(msg.sender)
                receivers_list[i].unread_msgs_count += 1
                unread_msgs_count += 1

            # if msg.status == 'sended':
            #     i = receivers_list.index(msg.sender)
            #     receivers_list[i].unread_msgs_count += 1
            #     unread_msgs_count += 1

        # if msg.receiver == user:# and (not cur_receiver or msg.sender != cur_receiver):
        # if msg.status == 'sended':
        #     i = receivers_list.index(msg.sender)
        #     receivers_list[i].unread_msgs_count += 1
        #     unread_msgs_count += 1

    return receivers_list, unread_msgs_count

    # receivers_list.extend((item.sender for item in receivers if item.sender != user))
    # receivers_list.extend((item.receiver for item in receivers if item.receiver != user))
    #
    # return list(set(receivers_list))


def get_tickets_Dict_by_manager(user):
    tickets = MsgGroup.objects.filter(enable=True, manager=user).order_by('-modifiedDT')

    Dict = {
        'tickets': tickets,
    }
    return Dict

def get_messages_for_ticket(ticket):
    return ticket.rel_messages_for_group.filter(enable=True).order_by('-modifiedDT')


def get_ticketsDict_for_staff(user):
    Dict = {
        'tickets_wo_manager': get_tickets_wo_manager(),
        'tickets_for_manager': get_tickets_for_manager(user),
    }
    return Dict

def get_tickets_wo_manager():

    tickets = MsgGroup.objects.filter(
        enable=True, manager=None
    ).annotate(
        unread_msgs_count=V(1)
    ).order_by('-modifiedDT')


    return tickets

def get_tickets_for_manager(user):
    unread_msgs = Message.objects.filter(
        group=31, status='sended', receiver=user
    )

    unread_msgs = Message.objects.filter(
        group=OuterRef('pk'), status='sended', receiver=user
    ).values('id')[:1]

    msgs = Message.objects.filter(
        group=OuterRef('pk')
    ).order_by('-modifiedDT').values('modifiedDT')[:1]

    tickets = MsgGroup.objects.filter(
        enable=True, manager=user
    ).annotate(
        unread_msgs_count = Count(Subquery(unread_msgs)),
        last_msg_modifiedDT = Subquery(msgs)
        # unread_msgs_count=Count(
        #     'rel_messages_for_group',
        #     filter=Q(rel_messages_for_group__status='sended', rel_messages_for_group__receiver=user)
        # )
    ).order_by('-unread_msgs_count', '-last_msg_modifiedDT')


    return tickets