from django.db.models import Sum, Count, Q
from django.db.models.functions import Coalesce

from apps.herd.models import Rancher, Herd
from apps.herd.services.services import rancher_quota_weight
from apps.product.models import OrganizationQuotaStats
from apps.warehouse.models import InventoryQuotaSaleItem
from apps.warehouse.services.services import can_buy_from_inventory


class RancherDashboardService:
    """
    Rancher Dashboard Service
    """

    @staticmethod
    def get_main_dashboard(
            self,
            rancher_search_fields: list[str] = None,
            herd_search_fields: list[str] = None,
            query_string: str = None
    ):
        """
        get ranchers main page dashboard
        """
        ranchers = Rancher.objects.all()
        herds = Herd.objects.all()

        ranchers_data = ranchers.aggregate(
            total_ranchers_count=Coalesce(Count("id"), 0),
            total_with_herd=Coalesce(Count("id", filter=Q(without_herd=False)), 0),
            total_without_herd=Coalesce(Count("id", filter=Q(without_herd=True)), 0),
            total_natural_ranchers=Coalesce(Count("id", filter=Q(rancher_type='N')), 0),
            total_legal_ranchers=Coalesce(Count("id", filter=Q(rancher_type='L')), 0),
            total_industrial_ranchers=Coalesce(Count("id", filter=Q(activity='I')), 0),
            total_village_ranchers=Coalesce(Count("id", filter=Q(activity='V')), 0),
            total_nomadic_ranchers=Coalesce(Count("id", filter=Q(activity='N')), 0),
        )

        herds_data = herds.aggregate(
            total_herds_count=Coalesce(Count("id"), 0),
            total_industrial_herds_count=Coalesce(Count("id", filter=Q(activity='I')), 0),
            total_Village_herds_count=Coalesce(Count("id", filter=Q(activity='V')), 0),
            total_nomadic_herds_count=Coalesce(Count("id", filter=Q(activity='N')), 0),
            total_heavy_livestock_count=Coalesce(Sum("heavy_livestock_number"), 0),
            total_light_livestock_count=Coalesce(Sum("light_livestock_number"), 0),
        )

        return {"rancher_dashboard": ranchers_data, "herd_dashboard": herds_data}

    @staticmethod
    def get_rancher_dashboard(self, rancher: Rancher):
        """
        get rancher dashboard
        """

        rancher_data = rancher.herd.aggregate(
            total_herds_count=Coalesce(Count("id"), 0),
            total_heavy_livestock_count=Coalesce(Sum("heavy_livestock_number"), 0),
            total_light_livestock_count=Coalesce(Sum("light_livestock_number"), 0),
        )

        transaction_sale_items = InventoryQuotaSaleItem.objects.select_related(
            'transaction', 'quota_stat'
        ).filter(
            transaction__rancher=rancher,
            # transaction__transaction_status='success',
        ).aggregate(
            total_purchased_weight=Coalesce(Sum('weight'), 0),
        )

        rancher_data.update(transaction_sale_items)

        return rancher_data

    @staticmethod
    def get_rancher_dashboard_by_quota_usage(self, rancher: Rancher):
        """
        get rancher dashboard by quota usage
        """

        # get organization quota stats of transaction item
        quota_stat = OrganizationQuotaStats.objects.filter(stat_type='quota', quota__is_closed=False)

        available_stats = [
            stat for stat in quota_stat if (
                    can_buy_from_inventory(rancher, quota_stat=stat) and rancher is not None
            )
        ]

        rancher_data_by_quota_usage = []
        for stat in available_stats:
            rancher_quota_data = rancher_quota_weight(rancher=rancher, quota=stat.quota, quota_stat=stat)
            rancher_quota_data.update({'product': stat.quota.product.name})
            rancher_data_by_quota_usage.append(rancher_quota_data)

        return rancher_data_by_quota_usage

    @staticmethod
    def get_rancher_dashboard_by_product_usage(self, rancher: Rancher):
        """
        get rancher dashboard by product usage
        """

        # get organization quota stats of transaction item
        quota_stat = OrganizationQuotaStats.objects.filter(stat_type='quota', quota__is_closed=False)

        available_stats = [
            stat for stat in quota_stat if (
                    can_buy_from_inventory(rancher, quota_stat=stat) and rancher is not None
            )
        ]

        rancher_data_by_quota_usage = []
        for stat in available_stats:
            rancher_quota_data = rancher_quota_weight(rancher=rancher, quota=stat.quota, quota_stat=stat)
            rancher_quota_data.update({
                'product': stat.quota.product.name,
                'product_id': stat.quota.product.id,
                'quota_id': stat.quota.quota_id,
            })
            rancher_data_by_quota_usage.append(rancher_quota_data)

        product_list = set(stat.quota.product.id for stat in quota_stat)

        rancher_data_by_product_usage_list = []

        for prod in product_list:
            product_summary = {
                'product_id': prod,
                'product': None,
                'total_weight': 0,
                'remaining_weight': 0,
                'free_sale': 0,
                'total_purchase': 0,
                'items': []
            }

            for item in rancher_data_by_quota_usage:
                if item['product_id'] == prod:
                    product_summary['product'] = item['product']
                    product_summary['total_weight'] += item['total_weight']
                    product_summary['remaining_weight'] += item['remaining_weight']
                    product_summary['free_sale'] += item['free_sale']
                    product_summary['total_purchase'] += item['total_purchase']
                    product_summary['items'].append(item)

            rancher_data_by_product_usage_list.append(product_summary)

        return rancher_data_by_product_usage_list
