import json
from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer, JsonWebsocketConsumer
from asgiref.sync import async_to_sync, sync_to_async
# from channels.auth import channel_session_user, channel_session_user_from_http
from channels.layers import get_channel_layer
from django.template.loader import render_to_string


def send_to_support_managers_list_tickets_wo_manager(ticket, required_beep=False):
    from.funcs import get_tickets_wo_manager

    # рассылаем всем менеджерам сообщение

    Dict = {
        'ticket': ticket,
        'tickets_wo_manager': get_tickets_wo_manager()
    }
    tickets_wo_manager_html = render_to_string('widgets/w_tickets_wo_manager.html', Dict)

    group_name = 'support_managers'
    Dict = {
        'type': 'update_chat',
        'tickets_wo_manager_html': tickets_wo_manager_html,
        'required_beep': required_beep,
        'group_name': group_name,
    }
    if ticket.manager:
        Dict.update({'ticket_manager': ticket.manager.id})

    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        group_name,
        Dict
    )

    # ---------------------
    return True


def get_tickets_wo_manager_html(ticket, user, data):
    from .funcs import get_tickets_wo_manager

    # если не менеджер - возвращаем None
    if not ticket or ticket.manager.id != user.id:
        return None

    Dict = {
        'ticket': ticket,
        'tickets_wo_manager': get_tickets_wo_manager()
    }
    tickets_wo_manager_html = render_to_string('widgets/w_tickets_wo_manager.html', Dict)

    return tickets_wo_manager_html


def get_tickets_w_manager_html(ticket, user, data):
    from .funcs import get_tickets_for_manager

    # если не менеджер - возвращаем None
    if not ticket or ticket.manager.id != user.id:
        return None

    Dict = {
        'ticket': ticket,
        'tickets_for_manager': get_tickets_for_manager(user)
    }
    tickets_w_manager_html = render_to_string('widgets/w_tickets_w_manager.html', Dict)

    return tickets_w_manager_html


class ChatConsumer(WebsocketConsumer):

    # def __init__(self, *args, **kwargs):
    #     super().__init__(args, kwargs)
    #     self.room_name = None

    def disconnect(self, close_code):
        print("Closed websocket with code: ", close_code)

        for gr in self.groups:
            async_to_sync(self.channel_layer.group_discard)(
                gr,
                self.channel_name
            )
        self.close()

    def connect(self):
        print('ws connect')

        user_group = f'user_{self.scope["user"].id}'

        add_to_group = False
        if not self.groups or not user_group in self.groups or not self.channel_name in self.groups[user_group]:
            add_to_group = True

        if add_to_group:
            if not self.groups:
                self.groups = {user_group: [self.channel_name]}
            elif not user_group in self.groups:
                self.groups[user_group].append(self.channel_name)
            else:
                self.groups.update({user_group: [self.channel_name]})

            async_to_sync(self.channel_layer.group_add)(
                user_group,
                self.channel_name
            )

            print(f'created group user_{self.scope["user"].id}')

        if self.scope['user'].is_staff:
            async_to_sync(self.channel_layer.group_add)(
                f'support_managers',
                self.channel_name
            )
            print(f'add user {self.scope["user"].id} to group support_managers')

        self.accept()




    def receive(self, text_data=None, bytes_data=None):
        if len(text_data) < 500:
            print(f'ws receive text_data = {text_data}')
        else:
            print(f'ws receive text_data size = {len(text_data)}')

        import base64

        from AuthApp.models import User
        from .models import Message, MsgGroup


        data = json.loads(text_data)

        # if 'file' in data:
        #     file_Dict = json.loads(data['file'])
        #
        #     f = open(f'chat_file_storage/{file_Dict["file_name"]}', 'wb+')
        #     head, content = file_Dict['file'].split(',')
        #     content = base64.b64decode(content)
        #     f.write(content)
        #     f.close()

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



        from .funcs import send_msg, get_update_chat_Dict
        data.update({
            'cur_user': sender,
            'required_beep': False,
        })
        res = send_msg(data)
        if not res['msg'] or type(res['msg']) == str:
            data.update({'bad_manager': True})

        ticket = None

        if 'ticket_id' in data and data['ticket_id']:
            ticket = MsgGroup.objects.get(id=data['ticket_id'])
            # receiver_obj = User.objects.get(id=receiver)
            msgs = Message.objects.filter(
                receiver__id=sender, group__id=data['ticket_id']
            )
            msgs.update(status='seen')

            if 'required_update_tickets_list_wo_managers' in res and res['required_update_tickets_list_wo_managers']:
                send_to_support_managers_list_tickets_wo_manager(ticket, required_beep=False)

        Dict = get_update_chat_Dict(data)



        group_name = f'user_{sender}'
        resDict = {
            'type': 'update_chat',
            'sender': sender,
            'receiver': receiver,
            'group_name': group_name,

        }

        if ticket:
            tickets_wo_manager_html = get_tickets_wo_manager_html(ticket, sender_obj, data)
            if tickets_wo_manager_html:
                resDict.update({'tickets_wo_manager_html': tickets_wo_manager_html})

            tickets_w_manager_html = get_tickets_w_manager_html(ticket, sender_obj, data)
            if tickets_w_manager_html:
                resDict.update({'tickets_w_manager_html': tickets_w_manager_html})


        resDict.update(Dict)
        async_to_sync(self.channel_layer.group_send)(
            group_name,
            resDict
        )

        group_name = f'user_{receiver}'
        # if group_name in self.channel_layer.groups.keys():
        data.update({
            'cur_user': receiver,
            'required_beep': True,
        })
        Dict = get_update_chat_Dict(data)

        if 'support_chat_html' in Dict:
            msg_type = 'update_support_chat'
        else:
            msg_type = 'update_chat'

        resDict = {
            'type': msg_type,
            'sender': receiver,
            'receiver': sender,
            'group_name': group_name,
        }

        if ticket:
            tickets_wo_manager_html = get_tickets_wo_manager_html(ticket, receiver_obj, data)
            if tickets_wo_manager_html:
                resDict.update({'tickets_wo_manager_html': tickets_wo_manager_html})

            tickets_w_manager_html = get_tickets_w_manager_html(ticket, receiver_obj, data)
            if tickets_w_manager_html:
                resDict.update({'tickets_w_manager_html': tickets_w_manager_html})

        resDict.update(Dict)
        async_to_sync(self.channel_layer.group_send)(
            group_name,
            resDict
        )



    def echo(self, data):
        print('ws echo')

        self.send(text_data=json.dumps(data))

    def update_support_chat(self, data):
        print(f'ws update_support_chat {data["group_name"]}')

        self.send(text_data=json.dumps(data))

    def update_chat(self, data):
        print(f'ws update_chat {data["group_name"]}')

        self.send(text_data=json.dumps(data))

    def ws_send_msg(self, data):
        print('ws ws_send_msg')

        self.send(text_data=json.dumps(data))