import re

from django.db.models import Q
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny

from authentication.models import SystemUserProfile, Province, BankCard, City, Group, SystemAddress
from authentication.serializer.serializer import BankCardSerializer
from authentication.serializers import SystemAddressSerializer
from rest_framework.response import Response
from rest_framework import status
from panel.models import Wallet

COMPANY_NUMBER2='09169726704'
COMPANY_NUMBER='09011110919'
UNION_NUMBER='09188621910'
GUILD_NUMBER='09011110911'
UNION_SECOND_NUMBER='09184310081'
SUPPORTER_NUMBER='09165597588'
UNION_THIRD_NUMBER=None
UNION_FOURTH_NUMBER='09109906845'
UNION_NUMBER_2=None
UNION_FIFTH_NUMBER='09188621910'
UNION_SIXTH_NUMBER='09183487701'

# Remove Null Fields From Request Body
def remove_null_fields(type=None, request=None, item=None):
    if type == 'req':
        null_fields = []
        for key, value in request.data.items():
            if value is None:
                null_fields.append(key)
        for item in null_fields:
            request.data.pop(item)
    elif type == 'item':
        null_fields = []
        for key, value in request.data[item].items():
            if value is None:
                null_fields.append(key)
        for field in null_fields:
            request.data[item].pop(field)
    return request


def create_except_profile(request, queryset, serializer, role):
    # get user profile object
    userprofile = SystemUserProfile.objects.get(key=request.data['userprofile_key'])
    request.data.pop('userprofile_key')

    # if not queryset.objects.filter(user=userprofile).exists():

    # get group and set role for user
    group = Group.objects.get(name=role)
    userprofile.role.add(group)

    # get province object
    province = Province.objects.get(key=request.data['province'])
    request.data.pop("province")

    # get city object
    city = City.objects.get(key=request.data['city'])
    request.data.pop('city')

    # get user banking information
    if 'user_bank_info' in request.data.keys():
        bank_card = BankCard.objects.create(**request.data['user_bank_info'])
        request.data.pop('user_bank_info')
    else:
        bank_card = None
    wallet = Wallet()
    wallet.save()

    # create address object & operator object with serializers
    address_serializer = SystemAddressSerializer(data=request.data)
    if address_serializer.is_valid():
        address_obj = address_serializer.create(validated_data=request.data)
        address_obj.province = province
        address_obj.city = city
        address_obj.save()
        operator_object = queryset(
            user=userprofile,
            address=address_obj,
            user_bank_info=bank_card,
            wallet=wallet
        )
        operator_object.save()
        operator_serializer = serializer(operator_object)
        return operator_serializer.data, status.HTTP_201_CREATED, operator_object
    return address_serializer.errors, status.HTTP_400_BAD_REQUEST
    # else:
    #     return "operator exists", status.HTTP_403_FORBIDDEN


def update_except_profile(model, serializer, request):
    # remove null fields in address body
    request = remove_null_fields(type='item', request=request, item='address')
    # remove null fields in user bank info body
    request = remove_null_fields(type='item', request=request, item='user_bank_info')

    userprofile = SystemUserProfile.objects.get(user=request.user)
    operator = model.objects.get(user=userprofile)

    if 'address' in request.data.keys() or request.data['address'] is not None:
        address_serializer = SystemAddressSerializer(data=request.data['address'])
        if address_serializer.is_valid():
            addr_object = address_serializer.update(
                instance=operator.address,
                validated_data=request.data['address']
            )
            operator.address = addr_object

    if 'user_bank_info' in request.data.keys() or request.data['user_bank_info'] is not None:
        bank_serializer = BankCardSerializer(data=request.data['user_bank_info'])
        if bank_serializer.is_valid():
            bank_object = bank_serializer.update(
                instance=operator.user_bank_info,
                validated_data=request.data['user_bank_info']
            )
            operator.user_bank_info = bank_object
    operator.save()
    response_serializer = serializer(operator)
    return response_serializer


def operator_update_except_profile(model, serializer, request):
    # remove null fields in address body
    request = remove_null_fields(type='item', request=request, item='address')
    # remove null fields in user bank info body
    request = remove_null_fields(type='item', request=request, item='user_bank_info')

    userprofile = SystemUserProfile.objects.get(key=request.data['userprofile_key'])
    request.data.pop('userprofile_key')
    if 'poultry_key' in request.data.keys():
        if 'unit_name' in request.data.keys():
            unit_name = request.data['unit_name']
            request.data.pop('unit_name')

        else:
            unit_name = None

        if 'halls' in request.data.keys():
            halls = int(request.data['halls'])
            request.data.pop('halls')

        else:
            halls = None

        if 'breeding_unique_id' in request.data.keys():
            breeding_unique_id = request.data['breeding_unique_id']
            request.data.pop('breeding_unique_id')

        else:
            breeding_unique_id = None

        operator = model.objects.get(key=request.data['poultry_key'])

        request.data.pop('poultry_key')
        if halls != None:
            operator.number_of_halls = halls
            operator.save()
        if unit_name != None:
            operator.unit_name = unit_name
            operator.save()
        if breeding_unique_id != None:
            operator.breeding_unique_id = breeding_unique_id
            operator.save()


    else:
        operator = model.objects.get(user=userprofile)

    if 'address' in request.data.keys() or request.data['address'] is not None:
        data = request.data['address']
        if 'city' in request.data['address']:
            city = City.objects.get(key=request.data['address']['city'])  # contains city object
            data.pop('city')
        else:
            city = None

        if 'province' in request.data['address']:
            province = Province.objects.get(key=request.data['address']['province'])  # contains province object
            data.pop('province')
        else:
            province = None

        address = SystemAddress.objects.get(key=operator.address.key)
        if province != None:
            address.province = province
        if city != None:
            address.city = city
        address.save()

        address_serializer = SystemAddressSerializer(data=data)
        if address_serializer.is_valid():
            addr_object = address_serializer.update(
                instance=operator.address,
                validated_data=request.data['address']
            )
            if city != None:
                addr_object.city = city
            if province != None:
                addr_object.province = province
            addr_object.save()
            operator.address = addr_object

    if 'user_bank_info' in request.data.keys() or request.data['user_bank_info'] != "":
        if operator.user_bank_info is not None:
            bank_serializer = BankCardSerializer(data=request.data['user_bank_info'])
            if bank_serializer.is_valid():
                bank_object = bank_serializer.update(
                    instance=operator.user_bank_info,
                    validated_data=request.data['user_bank_info']
                )
                operator.user_bank_info = bank_object
        else:
            bank_serializer = BankCardSerializer(data=request.data['user_bank_info'])
            if bank_serializer.is_valid():
                bank_object = bank_serializer.create(
                    validated_data=request.data['user_bank_info']
                )
                operator.user_bank_info = bank_object
    operator.save()
    response_serializer = serializer(operator)
    return response_serializer


def check_mobile_number(s):
    pattern = r'^09\d{9}$'
    return bool(re.match(pattern, s))

@api_view(["GET"])
@csrf_exempt
@permission_classes([AllowAny])
def get_country(request):
    asian_countries = {
        'Iraq': 'عراق',
        'Afghanistan': 'افغانستان',
        'Turkey': 'ترکیه',

    }

    persian_country_details = [{'en': eng_name, 'fa': persian_name} for eng_name, persian_name in
                               asian_countries.items()]

    return Response(persian_country_details)

def build_query(filterset_class, value):
    query = Q()
    for field in filterset_class.Meta.fields:
        query |= Q(**{f"{field}__icontains": value})
    return query