from decimal import Decimal
from apps.herd.models import Rancher
from apps.livestock.models import LiveStock
from apps.warehouse.models import InventoryEntry
from apps.product.models import Quota
import typing


def get_rancher_statistics(rancher: Rancher = None) -> typing.Any:
    """ get statistics of a rancher """  # noqa

    herds = rancher.herd.all()  # noqa
    herd_count = herds.count()

    livestocks = LiveStock.objects.filter(herd__in=herds)  # noqa

    light_count = livestocks.filter(weight_type='L').count()
    heavy_count = livestocks.filter(weight_type='H').count()

    sheep_count = livestocks.filter(type__name="گوسفند").count()  # noqa
    goat_count = livestocks.filter(type__name="بز").count()
    cow_count = livestocks.filter(type__name="گاو").count()
    camel_count = livestocks.filter(type__name="شتر").count()
    horse_count = livestocks.filter(type__name="اسب").count()

    return {
        "herd_count": herd_count,
        "light_count": light_count,
        "heavy_count": heavy_count,
        "sheep_count": sheep_count,
        "goat_count": goat_count,
        "cow_count": cow_count,
        "camel_count": camel_count,
        "horse_count": horse_count,
    }


def rancher_quota_weight(rancher, inventory_entry: InventoryEntry):
    """
    :param rancher: Rancher instance
    :param inventory_entry: InventoryEntry instance
    :return: dict {total, by_type}
    """

    live_stock_meta = {
        "گوسفند": "sheep_count",  # noqa
        "بز": "goat_count",
        "گاو": "cow_count",
        "شتر": "camel_count",
        "اسب": "horse_count"
    }

    quota: Quota = inventory_entry.distribution.quota
    allocations = quota.livestock_allocations.all()

    livestock_counts = get_rancher_statistics(rancher)

    total_weight = Decimal(0)
    details = {}

    for alloc in allocations:
        animal_type = alloc.livestock_type.name
        per_head = Decimal(alloc.quantity_kg)
        count = livestock_counts.get(live_stock_meta.get(animal_type), 0)

        weight = per_head * Decimal(count)
        details[animal_type] = weight
        total_weight += weight

    return {
        "total": total_weight,
        "by_type": details
    }
