import traceback

from rest_framework import serializers

from core.settings_vars import DEBUG, METASERVICE_NAME, EJ_HOST, EJ_SERVICE
from dbsynce.lib.core import *
from dbsynce.lib.ejabberd import *
from dbsynce.models import Orders
from tickets.models import Ticket, TicketList


class OrdersSerializer(serializers.ModelSerializer):
    class Meta:
        model = Orders
        fields = '__all__'

    def create(self, validated_data):
        ModelClass = self.Meta.model

        if "ticket" not in validated_data:
            # Create ticket with minimal required data
            ticket_data = {
                "ticket_list": TicketList.objects.get(pk=9),  # MS-SUP входящие обычные заявки ST_REQUEST
                "status": None,
                "created_date": "2000-01-01",  # mandatory
                "status_changed_date": None,
                "created_by": None,
                "priority": 0,  # default: 0
                "type": None,
                "title": "New ticket title",  # mandatory
                "note": None,
                "due_date": None,
                "assigned_to": None,
            }
            ticket_instance = Ticket._default_manager.create(**ticket_data)
            validated_data["ticket"] = ticket_instance

        try:
            instance = ModelClass._default_manager.create(**validated_data)
        except TypeError:
            tb = traceback.format_exc()
            msg = (
                    'Got a `TypeError` when calling `%s.%s.create()`. '
                    'This may be because you have a writable field on the '
                    'serializer class that is not a valid argument to '
                    '`%s.%s.create()`. You may need to make the field '
                    'read-only, or override the %s.create() method to handle '
                    'this correctly.\nOriginal exception was:\n %s' %
                    (
                        ModelClass.__name__,
                        ModelClass._default_manager.name,
                        ModelClass.__name__,
                        ModelClass._default_manager.name,
                        self.__class__.__name__,
                        tb
                    )
            )
            raise TypeError(msg)
        else:
            # FIXME: черновик, нужно возможно починить, дочинить переделать
            if DEBUG: print("[CREATING EJABBER ROOMS]")
            # Get neccessary data
            order_num = instance.pk
            support = choose_support()
            client = instance.client.user.phone_number
            provider = instance.provider.user.phone_number

            for room_name, room_members in get_rooms(METASERVICE_NAME, order_num, support, client, provider).items():
                # Create ejabber rooms
                data = {
                    "name": room_name,
                    "service": EJ_SERVICE,
                    "host": EJ_HOST,
                }
                res = ej_execute("create_room", data)
                if DEBUG: print(f"[RESPONSE CREATED]: {res.json()}")
                if DEBUG: print(f"[ROOM]: {room_name}")

                # Set rooms to members_only
                data = {
                    "name": room_name,
                    "service": EJ_SERVICE,
                    "option": "members_only",
                    "value": "true"
                }
                res = ej_execute("change_room_option", data)
                if DEBUG: print(f"[SET ROOM TO MEMBERS ONLY]: {res.json()}")

                """
                Add members to the room

                member_account is a dict that contains members credentials
                Key - the same thing that is in room_members
                Value - tuple (jid, ejabber affiliation).
                Affiliation can be one of: owner, admin, member, outcast, none.
                owner > admin
                """
                members_accounts = {
                    "owner": (METASERVICE_NAME + "_backend@" + EJ_HOST, "owner"),
                    "client": (client, "member"),
                    "support": (support, "member"),
                    "provider": (provider, "member"),
                }
                data = {
                    "name": room_name,
                    "service": EJ_SERVICE,
                    "jid": METASERVICE_NAME + "_backend@" + EJ_HOST,
                    "affiliation": "owner"
                }
                # Add all neccessary member to the room
                for member in room_members:
                    data["jid"] = members_accounts[member][0]
                    data["affiliation"] = members_accounts[member][1]
                    res = ej_execute("set_room_affiliation", data)
                    if DEBUG: print(f"[ADDED USER]: {res.json()}")
        return instance