# encoding: utf-8

from typing import (
    Dict,
    List,
    Tuple
)

from benefitsreport.repository import BenefitsOrderRepository


class BenefitsReport(object):
    def __init__(self, order_repository):
        # type: (BenefitsOrderRepository) -> None

        self.order_repository = order_repository

    def get_benefits_orders_detailed(
            self,
            initial_date,   # type: str
            end_date,       # type: str
            operator_id,    # type: str
            benefits        # type: Dict
    ):
        # type: (...) -> Dict[str, list]

        orders = self.order_repository.get_benefits_orders_detailed(
            initial_date,
            end_date,
            operator_id,
            benefits
        )

        report_data = {}
        for item in orders:
            benefit = {
                "order_id": item["order_id"],
                "ordered_qty": item["ordered_qty"],
                "product_unit_price": item["product_unit_price"],
                "product_name": item["product_name"],
                "benefit_total_value": item["benefit_total_value"],
                "order_time": item["order_time"],
                "operator": item["operator"],
                "discount_type": item["discount_type"],
                "total_gross": item["total_gross"]
            }
            benefits_for_period = report_data.setdefault(item["business_period"], [])
            benefits_for_period.append(benefit)

        return report_data

    def get_benefits_orders_consolidated(
            self,
            initial_date,  # type: str
            end_date,  # type: str
            operator_id  # type: str
    ):
        # type: (...) -> Dict[str, Tuple[int, float, float, str]]

        def merge_benefits(
                benefits  # type: List[Dict[str, Dict]]
        ):
            # type: (...) -> Dict[str, Tuple[int, float, float, str]]

            i_quantity = 0
            i_product_unit_price = 1
            i_benefit_total_value = 2

            merged = {}
            for benefit_data in benefits:
                for benefit_id, benefit in benefit_data.items():
                    if benefit["quantity"] > 0.0:
                        merged.setdefault(
                            benefit_id,
                            [
                                0,  # i_quantity
                                0.0,  # i_product_unit_price
                                0.0,  # i_benefit_total_value
                                benefit["benefit_user_description"],
                            ]
                        )
                        merged[benefit_id][i_quantity] += benefit["quantity"]
                        merged[benefit_id][i_benefit_total_value] += benefit["benefit_total_value"]
                        merged[benefit_id][i_product_unit_price] += (
                            benefit["quantity"] * benefit["product_unit_price"]
                        )

            return {k: tuple(v) for k, v in merged.items()}

        report_data = merge_benefits(
            self.order_repository.get_benefits_orders_consolidated(
                initial_date,
                end_date,
                operator_id
            )
        )

        return report_data
