import json

from typing import (
    Any,
    List,
    Dict,
)


def set_table_loyalty_to_order(
    table,          # type: Dict[str, Any]
    properties,     # type: Dict[str, Any]
):
    # type: (...) -> None

    loyalty_id = (table.get("properties", {}) or {}).get("LOYALTY_TABLE_ID", "{}")
    customers_info = (table.get("properties", {}) or {}).get("LOYALTY_TABLE_CUSTOMER_INFO", "{}")
    all_loyalty_benefits = (table.get("properties", {}) or {}).get("LOYALTY_TABLE_CUSTOMER_BENEFITS", "{}")
    loyalty_benefits_to_apply = (table.get("properties", {}) or {}).get("LOYALTY_TABLE_COUPONS_TO_APPLY_ON_TOTAL", "{}")
    loyalty_id = json.loads(s=loyalty_id)
    customers_info = json.loads(s=customers_info)
    all_loyalty_benefits = json.loads(s=all_loyalty_benefits)
    loyalty_benefits_to_apply = json.loads(s=loyalty_benefits_to_apply)

    joined_all_loyalty_benefits = []
    joined_loyalty_benefits_to_apply = []

    for key, benefits_ids in loyalty_benefits_to_apply.items():
        if key == "from_seat":
            continue
        current_benefits_ids = benefits_ids[:]
        if key != "table":
            current_benefits_ids = [
                "{}_{}".format(
                    c,
                    key,
                ) for c in current_benefits_ids
            ]
        joined_loyalty_benefits_to_apply.extend(current_benefits_ids)

    for key, benefits in all_loyalty_benefits.items():
        current_benefits = benefits[:]
        if key != "table":
            current_benefits = _set_seat_in_benefits(
                benefits=current_benefits,
                seat=key,
            )
        joined_all_loyalty_benefits.extend(current_benefits)

    if joined_all_loyalty_benefits:
        properties["LOYALTY_CUSTOMER_BENEFITS"] = json.dumps(obj=joined_all_loyalty_benefits)

    if joined_loyalty_benefits_to_apply:
        properties["LOYALTY_COUPONS_TO_APPLY_ON_TOTAL"] = json.dumps(obj=joined_loyalty_benefits_to_apply)

    loyalty_table = loyalty_id.get("table", "")
    if loyalty_table:
        properties["LOYALTY_ID"] = str(loyalty_table)

    customer_info_table = customers_info.get("table", {})
    if customer_info_table:
        properties["LOYALTY_CUSTOMER_INFO"] = json.dumps(obj=customer_info_table)


def _set_seat_in_benefits(
    benefits,   # type: List[Dict]
    seat,       # type: str
):
    # type: (...) -> List[Dict]

    seat = int(seat) if seat.isdigit() else None

    if not seat:
        return []
    seat_dict = dict(seat=seat)

    for benefit in benefits:
        benefit.update(dict(id="{}_{}".format(
            benefit.get("id", ""),
            seat,
        )))

        benefit.update(dict(userDescription="$LOYALTY_USER_DESCRIPTION_COUPON_WITH_SEAT|{}|{}".format(
            benefit.get("userDescription", "").encode("utf-8"),
            seat,
        )))

        action_keys = benefit.get("actions", {}).keys()
        for key in action_keys:
            action = benefit.get("actions", {}).get(key, "")
            if "discountPercentageOnTotal" in action or "discountAmountOnTotal" in action:
                action.update(seat_dict)
                continue
            action_type = action.keys()
            action_type = action_type[0] if len(action_type) == 1 else None
            if not action_type:
                continue
            for item in action.get(action_type, []):
                item.update(seat_dict)

    return benefits

