from collections import defaultdict

from apps.product.models import (
    Quota,
    QuotaLivestockAllocation,
    QuotaPriceCalculationItems,
    QuotaFinalPriceTypes
)
from apps.warehouse.models import InventoryEntry
from apps.herd.models import Rancher
from django.db.models import Sum
import typing


def get_products_in_warehouse(organization_id):
    """ get list of products from organization warehouse """

    entries = InventoryEntry.objects.select_related(
        'distribution__quota__product'
    )

    product_objects = [
        entry.distribution.quota.product for entry in entries
    ]

    return list(set(product_objects))


def quota_live_stock_allocation_info(quota: Quota) -> typing.Any:
    """ information of quota live stock allocations """

    allocations = quota.livestock_allocations.select_related('livestock_type')

    if allocations:
        allocations_list = [{
            "name": alloc.livestock_type.name,
            "quantity": alloc.quantity_kg,
            "type": alloc.livestock_type.weight_type
        } for alloc in allocations]

        return allocations_list


def quota_incentive_plans_info(quota: Quota, rancher: Rancher) -> typing.Any:
    """ information of quota incentive plans """

    incentive_plans = quota.incentive_assignments.select_related("livestock_type", "incentive_plan")

    if incentive_plans:
        incentive_plans_list = []
        for plan in incentive_plans:
            rancher_plan = plan.incentive_plan.rancher_plans.select_related(
                'rancher',
                'livestock_type'
            ).filter(rancher=rancher, livestock_type=plan.livestock_type)

            incentive_plans_data = {
                'id': plan.incentive_plan.id,
                'name': plan.incentive_plan.name,
                'livestock_type': plan.livestock_type.name if plan.livestock_type else "",
                'livestock_type_en': plan.livestock_type.en_name if plan.livestock_type else "",
                'livestock_weight_type': plan.livestock_type.weight_type if plan.livestock_type else "",
                'quantity_kg': plan.quantity_kg,
                'rancher_license_count': rancher_plan.first().allowed_quantity if rancher_plan else 0,
            }
            incentive_plans_list.append(incentive_plans_data)

        return incentive_plans_list


def quota_brokers_value(quota: Quota) -> typing.Any:
    """ information of quota brokers with their quota value """

    brokers = quota.broker_values.select_related("broker")

    if brokers:
        broker_values_list = [{
            'name': broker.broker.name,
            'amount': broker.value
        } for broker in brokers]

        return broker_values_list


def quota_attribute_value(quota: Quota) -> typing.Any:
    """ information of quota pricing attribute values """

    attributes = quota.attribute_values.select_related("attribute")

    if attributes:
        attribute_values_list = [{
            'name': attr.attribute.name,
            'amount': attr.value
        } for attr in attributes]

        return attribute_values_list


def quota_pricing_items_by_type(quota: Quota, sharing: list) -> typing.Any:
    """
    information of quota pricing items by final price type
    Optimized: fetch all pricing items once, group by pricing_type
    """

    # calculate pos sharing accounts total price
    # summation with bellow price items and set final total price in output
    calculate_sharing_total_price = sum(item['amount'] for item in sharing if item['amount'] is not None)

    items = (
        QuotaPriceCalculationItems.objects.filter(quota=quota).select_related(
            "pricing_type"
        ).values(
            "pricing_type_id",
            "pricing_type__en_name",
            "pricing_type__name",
            "name",
            "value"
        )
    )

    # split price items
    grouped = defaultdict(list)
    for item in items:
        key = item["pricing_type__en_name"]
        grouped[key].append({
            "name": item["name"],
            "value": item["value"]
        })

    # get total items price & final result
    result = []
    for en_name, group_items in grouped.items():
        total_price = sum(i["value"] for i in group_items if i["value"])
        fa_name = next(
            (i["pricing_type__name"] for i in items if i["pricing_type__en_name"] == en_name),
            en_name
        )
        result.append({
            'id': en_name,
            'items': group_items,
            "name": fa_name,
            "price": total_price,
            "total_price": total_price + calculate_sharing_total_price
        })

    return result
