import math
from logging import Logger

from production.model import ProductionOrder
from typing import (
    List,
    Optional,
)
from ._SplitterUtil import must_stay_in_main_order
from .._OrderChangerProductionBox import OrderChangerProductionBox


class SaleLinesOrderSplitter(OrderChangerProductionBox):
    def __init__(
        self,                   # type: SaleLinesOrderSplitter
        name,                   # type: str
        sons,                   # type: object
        max_lines,              # type: int
        logger=None,            # type: Optional[Logger]
    ):
        # type: (...) -> None

        super(SaleLinesOrderSplitter, self).__init__(name, sons, logger)
        self.max_lines = max_lines

    def change_order(
        self,       # type: SaleLinesOrderSplitter
        order,      # type: ProductionOrder
    ):
        # type: (...) -> List[ProductionOrder]

        if self.max_lines is None:
            return [order]

        limit = float(self.max_lines)
        temp_items = [x for x in order.items if not must_stay_in_main_order(x)]
        if len(temp_items) <= limit:
            return [order]

        orders = []
        split_index = 0
        box_limit = math.ceil(len(temp_items) / limit)
        items_per_box = math.ceil(len(temp_items) / box_limit)
        for item in temp_items:
            if len(orders) <= split_index:
                new_order = order.clone([], split_index)
                orders.append(new_order)

            orders[split_index].items.append(item)
            if len(orders[split_index].items) >= items_per_box:
                split_index += 1

        orders[0].items.extend([x for x in order.items if must_stay_in_main_order(x)])
        return orders
