from sysactions import StopAction

from application.domain import TableService
from model.customexception import InvalidTipError


class DoChangeTipInteractor(object):
    def __init__(self, table_service):
        # type: (TableService) -> None
        self.table_service = table_service

    def execute(self, pos_id, table_id, percentage, amount):
        # type: (str, str, str, str) -> str

        if (percentage != "" and percentage != "0") and (amount != "" and amount != "0"):
            raise InvalidTipError(code=InvalidTipError.ErrorCode.CANNOT_USE_TIP_BY_AMOUNT_AND_PERCENTAGE)
        elif percentage == "" and amount == "":
            raise InvalidTipError(code=InvalidTipError.ErrorCode.TIP_AMOUNT_MUST_BE_VALID)

        self._check_tip_amount(
            pos_id=pos_id,
            table_id=table_id,
            amount=amount,
            percentage=percentage,
        )

        if percentage != "":
            return self.table_service.change_service_tip(pos_id, table_id, percentage)
        if amount != "":
            return self.table_service.change_service_tip(pos_id, table_id, '', amount)

    def _check_tip_amount(
        self,           # type: DoChangeTipInteractor
        pos_id,         # type: str
        table_id,       # type: str
        amount,         # type: str
        percentage,     # type: str
    ):
        # type: (...) -> None

        from actions.fiscal import check_can_fiscalize_order

        order = self.table_service.get_table_orders(
            pos_id=pos_id,
            table_id=table_id,
        )[0]

        total_gross = float(order.total_gross or "0.0")
        if percentage != "":
            tip_amount = total_gross * float(percentage) / 100
        else:
            tip_amount = float(amount or "0.0")

        can_fiscalize_order = check_can_fiscalize_order(
            pos_id=pos_id,
            total_gross=total_gross,
            tip_amount=tip_amount,
        )
        if not can_fiscalize_order:
            raise StopAction()
