# -*- coding: utf-8 -*-
import json
import logging

from remove_coupon import remove_discounts
from mw_helper import (
    show_message_dialog,
    show_check_list_box_dialog
)
from sysactions import (
    get_model,
    get_current_order,
    format_amount,
    show_messagebox,
    get_posot,
    translate_message,
    StopAction
)
from xml.etree import cElementTree as eTree

from typing import (
    Dict,
    List,
    Union,
)

logger = logging.getLogger("PosActions")


def display_coupons(pos_id, table_id=None):
    model = get_model(pos_id)
    pos_ot = get_posot(model)
    order = get_current_order(model)
    if order is None:
        return

    try:
        benefits = get_benefits_from_order(pos_ot, order)
        if benefits is None or len(benefits) == 0:
            show_messagebox(pos_id, "$ORDER_HAS_NO_APPLIED_DISCOUNT")
            return

        applied_coupons = _get_applied_coupons_from_benefits(
            model=model,
            benefits=benefits,
        )
        selected_indexes = _select_coupon(pos_id, applied_coupons)
        if not len(selected_indexes):
            return

        coupon_ids = []
        for selected_index in selected_indexes:
            index = int(selected_index)
            if index == 0:
                continue

            coupon = [x for x in applied_coupons if x["index"] == index]
            if not coupon:
                continue

            disable = coupon[0]["name"].split("##")[2]
            if not eval(disable):
                coupon_ids.append(coupon[0]["id"])

        remove_discounts(
            pos_id,
            coupon_ids
        )
        if table_id is not None:
            from table_actions import process_discount_in_table, clean_table_payments, create_table_modified_event

            table_picture = clean_table_payments(pos_id, table_id, delete_order_tender=False)
            create_table_modified_event(pos_id, table_picture)

            process_discount_in_table(pos_id, order, table_id)

        return True

    except StopAction:
        raise
    except Exception as ex:
        show_message_dialog(pos_id, "$ERROR", ex.message)
        logger.exception("Error removing discount")
        return False


def get_benefits_from_order(pos_ot, order, custom_properties=None):
    if not order:
        return []

    if not custom_properties:
        custom_properties = eTree.XML(pos_ot.getOrderCustomProperties(orderid=order.get("orderId")))

    benefit_list_custom_property = custom_properties.find(".//OrderProperty[@key='BENEFIT_LIST']")
    if benefit_list_custom_property is None:
        return []

    benefit_list_json = json.loads(benefit_list_custom_property.get("value"))
    benefit_json = benefit_list_json.get("benefitList")
    benefit_list = json.loads(benefit_json)
    benefit_list = [b for b in benefit_list if b["benefit_applied"] or b["added_sale_lines"]]

    return benefit_list


def _get_applied_coupons_from_benefits(
    model,      # type: eTree.Element
    benefits,   # type: List[Dict[str, Union[int, bool, float, str, Dict]]]
):
    # type: (...) -> List[Dict[str, Union[int, str, None]]]

    all_coupons = translate_message(model, "ALL_COUPONS")
    applied_coupons = []
    total_amount = 0
    benefit_index = 1

    for benefit in benefits:
        benefit_applied = benefit.get("benefit_applied", False)
        if not benefit_applied:
            continue

        benefit_detail = benefit["benefit"]
        benefit_total_value = benefit["benefit_total_value"]
        if benefit_detail:
            added_sale_lines = len(benefit.get("added_sale_lines", []))
            if added_sale_lines and benefit_total_value <= 0:
                continue

            benefit_key = benefit["benefit_key"]
            benefit_description = benefit_detail.get("userDescription", benefit_detail.get("id", ""))
            description = benefit_description.encode("UTF-8")
            benefit_added_in_progress = benefit["order_state"] == "IN_PROGRESS"
            disable = benefit_added_in_progress or added_sale_lines > 0
            formatted_amount = format_amount(
                model=model,
                amount=benefit_total_value,
                addsymbol=False,
            )
            name = "{}##{}##{}".format(description, formatted_amount, disable)
            data = {"index": benefit_index, "id": benefit_key, "name": name}
            applied_coupons.append(data)

        benefit_index += 1
        total_amount += benefit_total_value

    name = "{}##{}##False".format(all_coupons, format_amount(model, total_amount, False))
    data = {"index": 0, "id": None, "name": name}
    applied_coupons.append(data)
    applied_coupons.sort(key=lambda x: (x["index"]))
    return applied_coupons


def _select_coupon(pos_id, coupons):
    options = ["{0}".format(c["name"]) for c in coupons]
    return show_check_list_box_dialog(pos_id, options, "$SELECT_ONE_COUPON", buttons="$REMOVE|$PREVIOUS")
