from xml.etree import cElementTree as eTree
from sysactions import (
    get_model,
    get_posot,
)
from services.model import DiscountAppliedRequest
from externals.repository import AlertsRepository
from services.model import ConfiguredAlert
from services.util import (
    get_configured_alerts_by_type,
    insert_event_into_repository,
    get_order_total,
)


class DiscountAppliedInteractor(object):
    def __init__(
        self,
        alerts_repository,  # type: AlertsRepository
    ):
        # type: (...) -> None

        self.alerts_repository = alerts_repository
        self.configured_alerts = self.alerts_repository.get_configured_alerts()

    def process_request(
        self,
        request,  # type: DiscountAppliedRequest
    ):
        # type: (...) -> None

        configured_alerts = get_configured_alerts_by_type(
            notify_type="DISCOUNT",
            configured_alerts=self.configured_alerts,
        )
        if not configured_alerts:
            return

        pos_id = request.pos_id
        order_id = request.order_id
        model = get_model(posid=pos_id)
        pos_ot = get_posot(model=model)
        order_picture = eTree.XML(pos_ot.orderPicture(orderid=order_id)).find("Order")

        discount_amount = float(order_picture.get("discountAmount"))
        total = get_order_total(order_picture=order_picture)
        discount_percentage = (discount_amount / total) * 100.0

        order_picture_dict = None
        table_picture_dict = None
        for alert in configured_alerts:
            valid_conditions = self._validate_alert(
                alert=alert,
                discount_amount=discount_amount,
                discount_percentage=discount_percentage,
            )
            if not valid_conditions:
                continue

            order_picture_dict, table_picture_dict = insert_event_into_repository(
                pos_id=pos_id,
                alerts_repository=self.alerts_repository,
                order_picture=order_picture,
                alert=alert,
                order_picture_dict=order_picture_dict,
                table_picture_dict=table_picture_dict,
            )

    @staticmethod
    def _validate_alert(
        alert,                # type: ConfiguredAlert
        discount_amount,      # type: float
        discount_percentage,  # type: float
    ):
        # type: (...) -> bool

        alert_conditions = alert.alert_json.get("conditions")

        has_discount_alert = "discountAmount" in alert_conditions
        discount_reached_alert_value = discount_amount >= float(alert_conditions.get("discountAmount"))
        if has_discount_alert and not discount_reached_alert_value:
            return False

        has_discount_alert = "discountPercentage" in alert_conditions
        discount_reached_alert_value = discount_percentage >= float(alert_conditions.get("discountPercentage"))
        if has_discount_alert and not discount_reached_alert_value:
            return False

        return True
