from application.model.benefit import ActionResult
from posot import OrderTaker
from typing import Dict

from application.model.order import Order
from application.model.transactions import AddBenefitToApplyUnitOfWork
from application.model.benefit import ActionTypes, Action
from application.model.conditions import Restrictions

from ._DiscountService import DiscountService
from ._OrderService import OrderService


class ActionService(object):
    def __init__(self, order_service, product_groups):
        # type: (OrderService, Dict) -> None

        self.order_service = order_service
        self.product_groups = product_groups

    def apply_action(self, action, burnt_items, uow, pos_ot, restriction, on_total):
        # type: (Action, Dict, AddBenefitToApplyUnitOfWork, OrderTaker, Restrictions, bool) -> ActionResult

        order = self.order_service.get_order(uow.pos_id, order_picture=uow.order.order_picture)
        discount_ids = Order.get_available_discount_ids(pos_ot)
        service = DiscountService(pos_ot, self.product_groups)
        result = ActionResult([], {}, [], {}, False, False)

        if order.order_state == "TOTALED":
            if action.name == ActionTypes.discountAmountOnTotal.value:
                result = service.apply_discount_amount_on_total(action, order, restriction, discount_ids)

            if action.name == ActionTypes.discountPercentageOnTotal.value:
                result = service.apply_discount_percentage_on_total(action, order, restriction, discount_ids)

            if action.name == ActionTypes.discountAmountByItems.value:
                result = service.apply_discount_amount_by_items(action, order, restriction, discount_ids, False)

            if action.name == ActionTypes.discountAmountByItemsOnTotal.value:
                result = service.apply_discount_amount_by_items(action, order, restriction, discount_ids, True)

            if action.name == ActionTypes.discountPercentageByItems.value:
                result = service.apply_discount_percentage_by_items(action, order, restriction, discount_ids, False)

            if action.name == ActionTypes.discountPercentageByGroupsOnTotal.value:
                result = service.apply_discount_percentage_by_groups(action, order, restriction, discount_ids, True)

            if action.name == ActionTypes.discountAmountByGroupsOnTotal.value:
                result = service.apply_discount_amount_by_groups(action, order, restriction, discount_ids, True)

            if action.name == ActionTypes.discountPercentageByItemsOnTotal.value:
                result = service.apply_discount_percentage_by_items(action, order, restriction, discount_ids, True)

            if action.name == ActionTypes.paymentAmount.value:
                result = service.apply_discount_amount_on_total_by_tender(action, order, restriction)

            if action.name == ActionTypes.paymentPercentage.value:
                result = service.apply_discount_percentage_on_total_by_tender(action, order, restriction)

            if action.name == ActionTypes.paymentAmountOnItem.value:
                result = service.apply_discount_amount_on_total_by_tender(action, order, restriction, True)

            if action.name == ActionTypes.itemsToAdd.value:
                result = service.apply_tender_on_added_items(action, order, uow.benefit_order_info)

            if result.benefit_applied:
                result.items_to_burn = order.get_items_to_burn(order, uow.benefit, burnt_items, self.product_groups)

            return result

        elif order.order_state == "IN_PROGRESS":
            if action.name == ActionTypes.itemsToAdd.value:
                return service.apply_items_to_add(action, burnt_items, uow, restriction)

            if on_total is False:
                result.items_to_burn = order.get_items_to_burn(order, uow.benefit, burnt_items, self.product_groups)
                result.pending_to_apply = True
                return result

        return ActionResult([], {}, [], {}, False, False)
