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

from LiveStock.Rancher.filterset import RancherFilterSet
from LiveStock.Rancher.serializers import RancherSerializer, RancherForBazrasiSerializer
from LiveStock.helpers import CustomPagination, build_query
from LiveStock.models import Rancher, Cooperative, LiveStock
from authentication.models import SystemUserProfile, City, Province
from LiveStock.Rancher.helpers import update_rancher, update_one_rancher
from django.contrib.auth.models import User, Group

from authentication.views import ARTA_URL_REGISTER, ARTA_URL_CHANGE_MOBILE_NUMBER
from panel.admin import PROJECT_API_KEY
import requests


class RancherViewSet(viewsets.ModelViewSet):
    queryset = Rancher.objects.filter(trash=False).only('herd_code', 'epidemiological_code', 'postal_code', 'unit_id',
                                                        'herd_name', 'national_id',
                                                        'fullname', 'mobile', 'contractor_code', 'city',
                                                        'registering_user', 'light_livestock', 'heavy_livestock', 'cow',
                                                        'goat', 'sheep', 'horse', 'camel', 'lot', 'lng',
                                                        'allow_buy').order_by('id')
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = RancherSerializer
    pagination_class = CustomPagination
    filterset_class = RancherFilterSet

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            rancher = user.rancher_user.all()

            serializer = self.serializer_class(rancher[0])
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if request.GET['role'] == 'Cooperative':
            cooperative = Cooperative.objects.get(user=user, trash=False)
            ranchers = Rancher.objects.filter(trash=False, city=cooperative.address.city.name).only('herd_code',
                                                                                                    'epidemiological_code',
                                                                                                    'postal_code',
                                                                                                    'unit_id',
                                                                                                    'herd_name',
                                                                                                    'national_id',
                                                                                                    'fullname',
                                                                                                    'mobile',
                                                                                                    'contractor_code',
                                                                                                    'city',
                                                                                                    'registering_user',
                                                                                                    'light_livestock',
                                                                                                    'heavy_livestock',
                                                                                                    'cow',
                                                                                                    'goat', 'sheep',
                                                                                                    'horse', 'camel',
                                                                                                    'lot', 'lng',
                                                                                                    'allow_buy').order_by(
                'id')

        else:
            ranchers = Rancher.objects.filter(trash=False).only('herd_code', 'epidemiological_code', 'postal_code',
                                                                'unit_id', 'herd_name', 'national_id',
                                                                'fullname', 'mobile', 'contractor_code', 'city',
                                                                'registering_user', 'light_livestock',
                                                                'heavy_livestock', 'cow',
                                                                'goat', 'sheep', 'horse', 'camel', 'lot', 'lng',
                                                                'allow_buy').order_by('id')

        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if search != 'undefined' and search.strip():
                ranchers = ranchers.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(ranchers)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(ranchers.first())
        # serializer = self.serializer_class(ranchers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        group = Group.objects.get(name__exact="Rancher")
        city = City.objects.get(name=request.data['city'])
        request.data.pop('city')
        province = Province.objects.get(key=city.province.key)
        system_profile = SystemUserProfile.objects.filter(mobile=request.data['mobile'], trash=False).last()
        if system_profile:
            if Rancher.objects.filter(user=system_profile, trash=False).exists():
                return Response({"result": "این اتحادیه قبلا ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)

        else:
            password = "123456"
            data = {
                "username": request.data['mobile'],
                "password": password,
                "api_key": PROJECT_API_KEY
            }
            req = requests.post(
                url=ARTA_URL_REGISTER,
                data=data,
                verify=False
            )

            if req.status_code == 200:
                user = User(username=request.data['mobile'], first_name=request.data['first_name'],
                            last_name=request.data['last_name'])
                user.save()
                base_id = SystemUserProfile.objects.all()
                if base_id.count() > 0:
                    base_id = int(base_id.last().base_order) + 1
                else:
                    base_id = 1000
                system_profile = SystemUserProfile(
                    mobile=request.data['mobile'],
                    first_name=request.data['first_name'],
                    last_name=request.data['last_name'],
                    fullname=request.data['first_name'] + " " + request.data['last_name'],
                    user=user,
                    base_order=base_id,
                    password=password,
                    national_id=request.data['national_id'],
                    city=city,
                    province=province
                )
                system_profile.save()
            else:
                return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است "}, status=status.HTTP_403_FORBIDDEN)
        system_profile.role.add(group)
        request.data.pop('first_name')
        request.data.pop('last_name')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            rancher = serializer.create(validated_data=request.data)
            rancher.user = system_profile
            rancher.save()
            return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        rancher = Rancher.objects.get(key=request.data['key'], trash=False)
        if 'first_name' in request.data.keys():
            # system_user_profile = SystemUserProfile.objects.get(key=rancher.user.key, trash=False)
            # system_user_profile.first_name = request.data['first_name']
            # system_user_profile.last_name = request.data['last_name']
            # system_user_profile.fullname = request.data['first_name'] + " " + request.data['last_name']
            # system_user_profile.save()
            # first_mobile_number = system_user_profile.mobile
            # second_mobile_number = request.data['mobile']
            # if first_mobile_number != second_mobile_number:
            #     if SystemUserProfile.objects.filter(mobile=second_mobile_number).exists():
            #         return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
            #                         status=status.HTTP_403_FORBIDDEN)
            #     data = {
            #         "first_mobile_number": first_mobile_number,
            #         "second_mobile_number": second_mobile_number,
            #     }
            #     req = requests.post(
            #         url=ARTA_URL_CHANGE_MOBILE_NUMBER,
            #         data=data,
            #         verify=False
            #     )
            #     if req.status_code == 200:
            #         second_mobile_number = second_mobile_number
            #         user = User.objects.get(id=system_user_profile.user.id)
            #         user.username = second_mobile_number
            #         user.save()
            #         system_user_profile.mobile = second_mobile_number
            #         system_user_profile.save()
            request.data.pop('first_name')
            request.data.pop('last_name')

        serializer = self.serializer_class(rancher)
        serializer.update(instance=rancher, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


    def destroy(self, request, pk=None, *args, **kwargs):
        rancher = Rancher.objects.get(key=request.GET["rancher_key"])
        rancher.trash = True
        rancher.save()
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


    # def update(self, request, *args, **kwargs):
    #     rancher = self.queryset.get(key=request.data['key'], trash=False)
    #     request.data.pop('key')
    #
    #     serializer = self.serializer_class(rancher)
    #     serializer.update(instance=rancher, validated_data=request.data)
    #     return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def get_detail_rancher(request):
    ranchers = Rancher.objects.filter(herd_code=request.GET['herd_code']).first()
    while True:
        update_ranchers = update_one_rancher(ranchers)
        if update_ranchers:
            break
    dict1 = {
        "light_livestock": ranchers.light_livestock,
        "heavy_livestock": ranchers.heavy_livestock,
        "sheep": ranchers.sheep,
        "goat": ranchers.goat,
        "cow": ranchers.cow,
        "camel": ranchers.camel,
        "horse": ranchers.horse
    }
    return Response(dict1, status=status.HTTP_200_OK)


class RancherForBazrasiViewSet(viewsets.ModelViewSet):
    queryset = Rancher.objects.filter(trash=False, type='industrial').only(
        'herd_code',
        'fullname',
        'mobile',
        'lot',
        'lng',
        'industrial',
        'heavy_livestock',
        'light_livestock'
    ).order_by('-industrial', 'id')
    permission_classes = [AllowAny]
    serializer_class = RancherForBazrasiSerializer

    def list(self, request, *args, **kwargs):
        type_filter = request.GET.get('type')
        queryset = Rancher.objects.filter(trash=False).only(
            'herd_code',
            'fullname',
            'mobile',
            'lot',
            'lng',
            'industrial',
            'heavy_livestock',
            'light_livestock',
            'type'
        ).order_by('-industrial', 'id')

        if type_filter in ('industrial', 'rural'):
            queryset = queryset.filter(type=type_filter)

        herd_codes = list(queryset.values_list('herd_code', flat=True))

        heavy_counts = {}
        light_counts = {}
        valid_herd_codes = set()
        if herd_codes:
            heavy_types = ('گاو', 'اسب', 'شتر')
            light_types = ('بز', 'گوسفند')
            livestock_counts = (
                LiveStock.objects.filter(
                    trash=False,
                    herd_code__in=herd_codes,
                    type__in=heavy_types + light_types
                )
                .values('herd_code', 'type')
                .annotate(total=Count('id'))
            )
            for item in livestock_counts:
                herd_code = item['herd_code']
                livestock_type = item['type']
                total = item['total']
                if livestock_type in heavy_types:
                    heavy_counts[herd_code] = heavy_counts.get(herd_code, 0) + total
                elif livestock_type in light_types:
                    light_counts[herd_code] = light_counts.get(herd_code, 0) + total

            valid_herd_codes = set(heavy_counts.keys()) | set(light_counts.keys())

        if valid_herd_codes:
            queryset = queryset.filter(herd_code__in=valid_herd_codes)
        else:
            queryset = queryset.none()

        serializer = self.get_serializer(
            queryset,
            many=True,
            context={
                'heavy_counts': heavy_counts,
                'light_counts': light_counts
            }
        )

        return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def dashboard_rancher(request):
    user = SystemUserProfile.objects.get(user=request.user, trash=False)
    role = request.GET.get('role')

    ranchers = Rancher.objects.filter(trash=False).values_list('herd_code', flat=True).distinct()

    live_stocks = LiveStock.objects.filter(trash=False, herd_code__in=ranchers).only('type')

    if role == 'Cooperative':
        cooperative = Cooperative.objects.get(user=user, trash=False)
        ranchers = Rancher.objects.filter(trash=False, city=cooperative.address.city.name).values_list('herd_code',
                                                                                                       flat=True).distinct()
        live_stocks = live_stocks.filter(herd_code__in=ranchers)

    value = request.GET.get('value')
    search = request.GET.get('search')
    if value and search == 'filter':
        if search != 'undefined' and search.strip():
            ranchers = ranchers.filter(build_query(RancherFilterSet.Meta.fields, value))

    counts = live_stocks.values('type').annotate(total=Count('id'))
    count_dict = {item['type']: item['total'] for item in counts}

    light_livestock = count_dict.get('بز', 0) + count_dict.get('گوسفند', 0)
    heavy_livestock = count_dict.get('گاو', 0) + count_dict.get('اسب', 0) + count_dict.get('شتر', 0)
    total_ranchers = len(ranchers)
    dhi_amount = ranchers.filter(dhi_amount__gt=1,trash=False).aggregate(total=Sum('dhi_amount'))['total'] or 0

    result = {
        'rancher_count': total_ranchers,
        'live_stocks_count': sum(count_dict.values()),
        "sheep": count_dict.get('گوسفند', 0),
        "goat": count_dict.get('بز', 0),
        "cow": count_dict.get('گاو', 0),
        "horse": count_dict.get('اسب', 0),
        "camel": count_dict.get('شتر', 0),
        "light_livestock": light_livestock,
        "heavy_livestock": heavy_livestock,
        "dhi_amount": dhi_amount,

    }

    return Response(result, status=status.HTTP_200_OK)
