from logging import Logger

from production.model import Item
from production.model import ProductionOrder
from typing import Dict, List, Optional
from ._OrderChangerProductionBox import OrderChangerProductionBox
from ._ProductionBox import ProductionBox


class OrderCostAdderBox(OrderChangerProductionBox):
    def __init__(
        self,               # type: OrderCostAdderBox
        name,               # type: str
        sons,               # type: List[ProductionBox]
        per_item_cost,      # type: Dict[int, int]
        default_cost,       # type: int
        logger=None,        # type: Optional[Logger]
    ):
        super(OrderCostAdderBox, self).__init__(name, sons, logger)
        self.per_item_cost = per_item_cost
        self.default_cost = default_cost

    def change_order(
        self,       # type: OrderCostAdderBox
        order,      # type: ProductionOrder
    ):
        # type: (...) -> ProductionOrder

        order.cost = self._add_cost_to_items(order.items)
        return order

    def _add_cost_to_items(
        self,       # type: OrderCostAdderBox
        items,      # type: List[Item]
    ):
        # type: (...) -> int

        order_points = 0
        for item in items:
            if item.is_product():
                order_points += self._get_item_cost(item)
            else:
                order_points += self._get_item_cost(item) + self._add_cost_to_items(item.items)

        return order_points

    def _get_item_cost(
        self,       # type: OrderCostAdderBox
        item,       # type: Item
    ):
        # type: (...) -> int
        if item.part_code in self.per_item_cost:
            item.cost = self.per_item_cost[item.part_code] * item.multiplied_qty
        else:
            item.cost = self.default_cost * item.multiplied_qty

        return item.cost
