package com.zm.order.tool.server.stream.convert;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zm.order.enums.*;
import com.zm.order.tool.server.constants.CommonConstants;
import com.zm.order.tool.server.constants.ExtFieldKeyMapping;
import com.zm.order.tool.server.constants.ResExtFieldKeyMapping;
import com.zm.order.tool.server.enums.BizTypeEnum;
import com.zm.order.tool.server.enums.DeliveryPlatformEnum;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.stream.SQLCategory;
import com.zm.order.tool.server.stream.factory.MapperFactory;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 抽象模型
 *
 * <p>
 * 数据流转换器
 * </p>
 *
 * @author nianchang
 * @date 2023/03/13 4:51 下午
 */
@SuppressWarnings("all")
public abstract class AbstractStreamConverter implements DataStreamConverter {

    public static final String BATCH_DATA = "collection";

    public static final String BATCH_DATA0 = "list";

    public static final String BAKING_E_SHOP = "from";

    public static final List<Integer> FILTER = Lists.newArrayList(4, 5, 6, 7, 8);

    private static final Logger logger = LoggerFactory.getLogger(AbstractStreamConverter.class);

    /**
     * 参数解析
     *
     * <p>
     * 将历史枚举值转换为新枚举值映射 兼容多表数据源解析场景，以DataStream模型为载体，只感知目标字段，其他字段不做处理
     *
     * 除了解析订单中的标准化字段，还需要将支付明细快照中的payType也重新设置为新的枚举
     * </p>
     *
     * @param data
     *            数据源
     * @param category
     *            SQL分类
     *
     * @return 数据源
     */
    public Object parse(Object data, SQLCategory category) {
        switch (category) {
            case ORDERS:
                Order order = JSON.parseObject(data.toString(), Order.class);
                DataStream dataStream = new DataStream(order);
                order.paint(convertIn(order.getBizType(), dataStream));
                mappingExtKey(order);
                paySnapshot(order, false, dataStream.getOrderType());
                return order;
            case ORDER_PAY_DETAILS:
                OrderPayDetails pay = JSON.parseObject(data.toString(), OrderPayDetails.class);
                pay.paint(convertIn(pay.getBizType(), new DataStream(pay)));
                return pay;
            case REFUNDS:
                Refund refund = JSON.parseObject(data.toString(), Refund.class);
                DataStream dataStream1 = new DataStream(refund);
                refund.paint(convertIn(refund.getBizType(), dataStream1));
                rebuildRefundDetail(refund, false, dataStream1.getOrderType());
                return refund;
            case REFUND_DETAILS:
                RefundDetail refundDetail = JSON.parseObject(data.toString(), RefundDetail.class);
                refundDetail.paint(convertIn(refundDetail.getBizType(), new DataStream(refundDetail)));
                return refundDetail;
            case COMMENT:
                OrderComment comment = JSON.parseObject(data.toString(), OrderComment.class);
                comment.paint(convertIn(comment.getBizType(), new DataStream(comment)));
                return comment;
            case ITEM_COMMENT:
                OrderItemComment itemComment = JSON.parseObject(data.toString(), OrderItemComment.class);
                itemComment.paint(convertIn(itemComment.getBizType(), new DataStream(itemComment)));
                return itemComment;
            default:
        }
        return data;
    }

    private void mappingExtKey(Order order) {
        Map<String, Object> extraMap = order.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            return;
        }
        List<String> removeKeys = new ArrayList<>();
        ExtFieldKeyMapping.MAPPING.forEach((key, newKey) -> {
            if (extraMap.containsKey(key)) {
                extraMap.put(newKey, extraMap.get(key));
                removeKeys.add(key);
            }
        });
        if (!CollectionUtils.isEmpty(removeKeys)) {
            for (String removeKey : removeKeys) {
                extraMap.remove(removeKey);
            }
        }
        order.setExtraMap(extraMap);
    }

    private DataStream convertIn(Integer bizType, DataStream data) {
        BizTypeEnum biz = BizTypeEnum.getValue(bizType);
        if (biz == null) {
            return data;
        }
        Integer orderType = data.getOrderType();
        Integer performance = data.getPerformanceType();
        DataStream stream = new DataStream(orderType, data.getOrderSubType(), data.getPerformanceType());

        switch (biz) {
            case BAKING:
                if (orderType != null) {
                    baking(bizType, data.getFeatures(), stream);
                }
                break;
            case CATERING:
            case ASSISTANT:
            case MEAL_MATE:
                if (performance != null) {
                    data.setPerformancePlatform(performance.toString());
                }
                if (orderType != null) {
                    catering(bizType, stream, performance, data.getPerformanceStatus(), data.getPerformancePlatform());
                }
                break;
            case MALL:
                if (orderType != null && orderType == 14) {
                    stream.setOrderType(OrderType.E_SHOP.getType());
                }
                if (orderType != null && orderType == 20) {
                    stream.setOrderType(OrderType.POINTS_OF_E_SHOP.getType());
                    stream.setOrderSubType(OrderSubType.GENERIC.getType());
                }
                if (data.getOrderSubType() != null && data.getOrderSubType() == 9) {
                    stream.setOrderSubType(OrderSubType.PRE_SELL.getType());
                }
            default:
        }

        stream.setSource(MapperFactory.orderSourceMap(bizType, data.getSource()));
        stream.setPayType(MapperFactory.payTypeMap(bizType, data.getPayType(), orderType));
        stream.setStatus(MapperFactory.orderStatusMap(bizType, data.getStatus()));
        stream.setRefundStatus(MapperFactory.refundStatusMap(bizType, data.getRefundStatus()));
        return stream;
    }

    private void baking(Integer bizType, String features, DataStream stream) {
        Integer orderType = stream.getOrderType();
        if (orderType == 1) {
            // 商城订单需要关联扩展字段中的from标识
            if (StringUtils.isNotBlank(features)) {
                Map extra = JSON.parseObject(features, Map.class);
                if (extra.get(BAKING_E_SHOP) != null) {
                    int from = Integer.parseInt(extra.get(BAKING_E_SHOP).toString());
                    if (from == 1) {
                        stream.setOrderType(OrderType.E_SHOP.getType());
                    }
                }
            }
            // 门店订单下的子类型映射
            if (stream.getOrderSubType() != null) {
                if (stream.getOrderSubType() == 3) {
                    stream.setOrderSubType(OrderSubType.MULTIPLE_USER.getType());
                } else if (stream.getOrderSubType() == 4) {
                    stream.setOrderSubType(OrderSubType.COLLECTIVE_BUYING.getType());
                } else if (stream.getOrderSubType() == 1) {
                    stream.setOrderSubType(OrderSubType.GROUP_BUYING.getType());
                } else if (stream.getOrderSubType() == 2) {
                    stream.setOrderSubType(OrderSubType.PRE_SELL.getType());
                } else if (stream.getOrderSubType() == 12) {
                    stream.setOrderSubType(OrderSubType.BLIND_POCKET_LOTTERY_DRAW.getType());
                } else if (stream.getOrderSubType() == 7) {
                    stream.setOrderSubType(OrderSubType.CAKE_PRE.getType());
                } else if (stream.getOrderSubType() == 6) {
                    stream.setOrderSubType(OrderSubType.BARGAIN.getType());
                } else if (stream.getOrderSubType() == 9) {
                    stream.setOrderSubType(OrderSubType.PROXY_SELL.getType());
                }
            }
        }
        // 买单订单
        else if (orderType == 2) {
            stream.setOrderType(OrderType.OFFLINE.getType());
        }
        // 储值订单
        else if (orderType == 3) {
            stream.setOrderType(OrderType.AMOUNT_OF_RECHARGE.getType());
            if (stream.getOrderSubType() != null && stream.getOrderSubType() == 5) {
                stream.setOrderSubType(OrderSubType.STORED_CARD_RECHARGE.getType());
            }
        }
        // 优惠券
        else if (orderType == 6) {
            stream.setOrderType(OrderType.COUPON.getType());
            stream.setOrderSubType(OrderSubType.COUPON.getType());
        } else if (orderType == 12) {
            stream.setOrderType(OrderType.COUPON.getType());
            stream.setOrderSubType(OrderSubType.COUPONS_OF_GROUP.getType());
        } else if (orderType == 30) {
            if (stream.getOrderSubType() != null && stream.getOrderSubType() == 1) {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.COUNT_CARD.getType());
            } else if (stream.getOrderSubType() != null && stream.getOrderSubType() == 2) {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.DY_WALLET.getType());
            } else if (stream.getOrderSubType() != null && stream.getOrderSubType() == 3) {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.WE_CHAT_VIDEO.getType());
            } else {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.DY_COUPON.getType());
            }
        }
        // 礼品卡
        else if (orderType == 4) {
            stream.setOrderType(OrderType.GIFT_CARD.getType());
            if (stream.getOrderSubType() != null && stream.getOrderSubType() == 8) {
                stream.setOrderSubType(OrderSubType.PHY_AMOUNT_CARD.getType());
            }
        }
        // 付费会员卡
        else if (orderType == 5) {
            stream.setOrderType(OrderType.MEMBERSHIP_CARD.getType());
            stream.setOrderSubType(OrderSubType.GENERIC.getType());
        }
        // 积分商城
        else if (orderType == 7) {
            stream.setOrderType(OrderType.POINTS_OF_E_SHOP.getType());
            stream.setOrderSubType(OrderSubType.GENERIC.getType());
        }
        // 活动订单
        else if (orderType == 60) {
            stream.setOrderType(OrderType.ACTIVITY.getType());
            stream.setOrderSubType(OrderSubType.BLIND_BOX_LOTTERY_DRAW.getType());
        } else if (orderType == 91) {
            stream.setOrderType(OrderType.ACTIVITY.getType());
            stream.setOrderSubType(OrderSubType.ACTIVITY_BOOKING.getType());
        }else{
            logger.info("[orderConvertNonMatch][orderType]baking, orderType :{}", orderType);
        }
    }

    private void catering(Integer bizType, DataStream stream, Integer oldPerfType, Integer perfStatus, String performancePlatform) {
        Integer orderType = stream.getOrderType();
        // 堂食、外卖等
        if (orderType == 1) {
            stream.setOrderType(OrderType.IN_STORE.getType());
            stream.setPerformanceType(PerformanceType.EAT_ON_SITE.getType());
        } else if (orderType == 2) {
            stream.setOrderType(OrderType.IN_STORE.getType());
            stream.setPerformanceType(PerformanceType.SELF_TAKE.getType());
        } else if (orderType == 3) {
            stream.setOrderType(OrderType.IN_STORE.getType());
            stream.setPerformanceType(PerformanceType.IN_CITY_DELIVERY.getType());
            if (Objects.equals(1, perfStatus) && StringUtils.isNotBlank(performancePlatform)) {
                stream.setPerformancePlatform(MapperFactory.platform(bizType, performancePlatform, orderType));
            }
        } else if (orderType == 35) {
            stream.setOrderType(OrderType.IN_STORE.getType());
            stream.setPerformanceType(PerformanceType.TAKEAWAY_SELF_TAKE.getType());
        }
        // 买单
        else if (orderType == 4) {
            stream.setOrderType(OrderType.OFFLINE.getType());
        } else if (orderType == 7) {
            stream.setOrderType(OrderType.OFFLINE.getType());
            stream.setOrderSubType(OrderSubType.PAY_CODE.getType());
        }
        // 商城订单
        else if (orderType == 14) {
            stream.setOrderType(OrderType.E_SHOP.getType());
            if (Objects.equals(5, stream.getPerformanceType())) {
                stream.setPerformanceType(1);
            }
        }
        // 活动订单
        else if (orderType == 40) {
            stream.setOrderType(OrderType.ACTIVITY.getType());
            if (stream.getOrderSubType() != null) {
                if (stream.getOrderSubType() == 60) {
                    stream.setOrderSubType(OrderSubType.BLIND_BOX_LOTTERY_DRAW.getType());
                } else if (stream.getOrderSubType() == 71) {
                    stream.setOrderSubType(OrderSubType.DRAW_LOTTERY_ACTIVITY.getType());
                } else if (stream.getOrderSubType() == 70) {
                    stream.setOrderSubType(OrderSubType.EXCHANGE_GOODS.getType());
                }
            }
            if (Objects.equals(5, oldPerfType)) {
                stream.setPerformanceType(1);
            }
        }
        // 优惠券
        else if (orderType == 12) {
            stream.setOrderType(OrderType.COUPON.getType());
            stream.setOrderSubType(OrderSubType.COUPONS_OF_GROUP.getType());
        } else if (orderType == 8) {
            stream.setOrderType(OrderType.COUPON.getType());
            if (stream.getOrderSubType() == null || stream.getOrderSubType() == 0) {
                stream.setOrderSubType(OrderSubType.COUPON.getType());
            } else if (stream.getOrderSubType() != null && stream.getOrderSubType() == 15) {
                stream.setOrderSubType(OrderSubType.ALI_PAY_GROUP_COUPON.getType());
            }
        } else if (orderType == 30) {
            if (stream.getOrderSubType() != null && stream.getOrderSubType() == 1) {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.COUNT_CARD.getType());
            } else if (stream.getOrderSubType() != null && stream.getOrderSubType() == 2) {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.DY_WALLET.getType());
            } else if (stream.getOrderSubType() != null && stream.getOrderSubType() == 3) {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.WE_CHAT_VIDEO.getType());
            } else {
                stream.setOrderType(OrderType.COUPON.getType());
                stream.setOrderSubType(OrderSubType.DY_COUPON.getType());
            }
        }
        // 礼品卡
        else if (orderType == 10) {
            stream.setOrderType(OrderType.GIFT_CARD.getType());
        }
        // 付费会员卡
        else if (orderType == 13) {
            stream.setOrderType(OrderType.MEMBERSHIP_CARD.getType());
        }
        // 储值订单
        else if (orderType == 5) {
            stream.setOrderType(OrderType.AMOUNT_OF_RECHARGE.getType());
        }
        // 正餐定金订单
        else if (bizType == 7 && orderType == 16) {
            stream.setOrderType(OrderType.DEPOSIT.getType());
        }
        // 积分商城
        else if (orderType == 11) {
            stream.setOrderType(OrderType.POINTS_OF_E_SHOP.getType());
            stream.setOrderSubType(OrderSubType.POINTS_COLL_CASH.getType());
        } else if (orderType == 20) {
            stream.setOrderType(OrderType.POINTS_OF_E_SHOP.getType());
            stream.setOrderSubType(OrderSubType.GENERIC.getType());
            if (Objects.equals(5, stream.getPerformanceType())) {
                stream.setPerformanceType(1);
            }
        } else {
            // todo 未匹配到告警，脱离现有整理的订单类型
            logger.info("[orderConvertNonMatch][orderType]catering, orderType :{}", orderType);
        }
    }

    private void paySnapshot(Order order, boolean isReverse, Integer oOrderType) {
        String payInfo = order.getPayDetailInfo();
        if (StringUtils.isNotBlank(payInfo) && !CommonConstants.PAY_FLAG.equals(payInfo)) {
            List<InnerOrderPayDetails> list = JSON.parseArray(payInfo, InnerOrderPayDetails.class);
            if (!CollectionUtils.isEmpty(list)) {
                for (InnerOrderPayDetails eachPay : list) {
                    // 依赖订单中的枚举值
                    // 支付类型会存在订单中记录的是组合支付，而支付明细记录的是支付明细，所以进行二次转换
                    eachPay.setPayType(
                        !isReverse ? MapperFactory.payTypeMap(order.getBizType(), eachPay.getPayType(), oOrderType)
                            : MapperFactory.reversePayTypeMap(order.getBizType(), eachPay.getPayType(), oOrderType));
                    eachPay.setSource(order.getSource());
                    eachPay.setOrderType(order.getOrderType());
                    eachPay.setPerformanceType(order.getPerformanceType());
                }
                order.setPayDetailInfo(JSON.toJSONString(list));
            }
        }
    }

    private void rebuildRefundDetail(Refund refund, boolean isReverse, Integer oOrderType) {
        String refundDetail = refund.getRefundDetailInfo();
        if (StringUtils.isNotBlank(refundDetail)) {
            List<InnerRefundDetail> list = JSON.parseArray(refundDetail, InnerRefundDetail.class);
            if (!CollectionUtils.isEmpty(list)) {
                for (InnerRefundDetail each : list) {
                    each.setPayType(
                        !isReverse ? MapperFactory.payTypeMap(refund.getBizType(), each.getPayType(), oOrderType)
                            : MapperFactory.reversePayTypeMap(refund.getBizType(), each.getPayType(), oOrderType));
                }
                refund.setRefundDetailInfo(JSON.toJSONString(list));
            }
        }
    }

    /**
     * 参数反解析
     *
     * <p>
     * 将新枚举值转换为老枚举值映射 兼容多表数据源解析场景，以DataStream模型为载体，只感知目标字段，其他字段不动
     * </p>
     *
     * @param data
     *            数据源
     * @param category
     *            SQL分类
     *
     * @return 数据源
     */
    public Object reverseParse(Object data, SQLCategory category) {
        switch (category) {
            case ORDERS:
                Order order = JSON.parseObject(data.toString(), Order.class);
                order.paint(convertOut(order.getBizType(), new DataStream(order)));
                reverseMappingExtKey(order);
                paySnapshot(order, true, order.getOrderType());
                return order;
            case ORDER_PAY_DETAILS:
                OrderPayDetails pay = JSON.parseObject(data.toString(), OrderPayDetails.class);
                pay.paint(convertOut(pay.getBizType(), new DataStream(pay)));
                return pay;
            case REFUNDS:
                Refund refund = JSON.parseObject(data.toString(), Refund.class);
                refund.paint(convertOut(refund.getBizType(), new DataStream(refund)));
                rebuildRefundDetail(refund, true, refund.getOrderType());
                return refund;
            case REFUND_DETAILS:
                RefundDetail refundDetail = JSON.parseObject(data.toString(), RefundDetail.class);
                refundDetail.paint(convertOut(refundDetail.getBizType(), new DataStream(refundDetail)));
                return refundDetail;
            case COMMENT:
                OrderComment comment = JSON.parseObject(data.toString(), OrderComment.class);
                comment.paint(convertOut(comment.getBizType(), new DataStream(comment)));
                return comment;
            case ITEM_COMMENT:
                OrderItemComment itemComment = JSON.parseObject(data.toString(), OrderItemComment.class);
                itemComment.paint(convertOut(itemComment.getBizType(), new DataStream(itemComment)));
                return itemComment;
            default:
        }
        return data;
    }

    private void reverseMappingExtKey(Order order) {
        Map<String, Object> extraMap = order.getExtraMap();
        if (CollectionUtils.isEmpty(extraMap)) {
            return;
        }
        List<String> removeKeys = new ArrayList<>();
        ResExtFieldKeyMapping.MAPPING.forEach((key, newKey) -> {
            if (extraMap.containsKey(key)) {
                extraMap.put(newKey, extraMap.get(key));
                removeKeys.add(key);
            }
        });
        if (!CollectionUtils.isEmpty(removeKeys)) {
            for (String removeKey : removeKeys) {
                extraMap.remove(removeKey);
            }
        }
        order.setExtraMap(extraMap);
    }

    private DataStream convertOut(Integer bizType, DataStream data) {
        BizTypeEnum biz = BizTypeEnum.getValue(bizType);
        if (biz == null) {
            return data;
        }
        Integer orderType = data.getOrderType();
        DataStream stream = new DataStream(orderType, data.getOrderSubType(), data.getPerformanceType());
        switch (biz) {
            case BAKING:
                if (orderType != null) {
                    reverseBaking(bizType, stream);
                }
                break;
            case ASSISTANT:
            case MEAL_MATE:
            case CATERING:
                if (orderType != null) {
                    reverseCatering(bizType, stream, data.getPerformanceType(), data.getPerformanceStatus(), data.getPerformancePlatform());
                }
                break;
            case MALL:
                if (Objects.equals(OrderType.E_SHOP.getType(), orderType)) {
                    stream.setOrderType(14);
                }
                if (Objects.equals(OrderType.POINTS_OF_E_SHOP.getType(), orderType)) {
                    stream.setOrderType(20);
                    stream.setOrderSubType(29);
                }
                if (Objects.equals(OrderSubType.PRE_SELL.getType(), data.getOrderSubType())) {
                    stream.setOrderSubType(9);
                }
            default:
        }

        stream.setSource(MapperFactory.reverseOrderSourceMap(bizType, data.getSource()));
        stream.setPayType(MapperFactory.reversePayTypeMap(bizType, data.getPayType(), stream.getOrderType()));
        stream.setStatus(MapperFactory.reverseOrderStatusMap(bizType, data.getStatus()));
        stream.setRefundStatus(MapperFactory.reverseRefundStatusMap(bizType, data.getRefundStatus()));
        return stream;
    }

    private void reverseBaking(Integer bizType, DataStream stream) {
        Integer orderType = stream.getOrderType();
        Integer orderSubType = stream.getOrderSubType();
        OrderType orderTypeRoute = OrderType.get(orderType);
        OrderSubType subTypeRoute = OrderSubType.get(orderSubType);
        switch (orderTypeRoute) {
            case IN_STORE:
                switch (subTypeRoute) {
                    case MULTIPLE_USER:
                        stream.setOrderSubType(3);
                        break;
                    case PRE_SELL:
                        stream.setOrderSubType(2);
                        break;
                    case GROUP_BUYING:
                        stream.setOrderSubType(1);
                        break;
                    case BARGAIN:
                        stream.setOrderSubType(6);
                        break;
                    case CAKE_PRE:
                        stream.setOrderSubType(7);
                        break;
                    case BLIND_POCKET_LOTTERY_DRAW:
                        stream.setOrderSubType(12);
                        break;
                    case COLLECTIVE_BUYING:
                        stream.setOrderSubType(4);
                        break;
                    default:
                }
                break;
            case E_SHOP:
                stream.setOrderType(1);
                switch (subTypeRoute) {
                    case PROXY_SELL:
                        stream.setOrderSubType(9);
                        break;
                    case BARGAIN:
                        stream.setOrderSubType(6);
                        break;
                    case CAKE_PRE:
                        stream.setOrderSubType(7);
                        break;
                    case BLIND_POCKET_LOTTERY_DRAW:
                        stream.setOrderSubType(12);
                        break;
                    case PRE_SELL:
                        stream.setOrderSubType(2);
                        break;
                    case GROUP_BUYING:
                        stream.setOrderSubType(1);
                        break;
                    case COLLECTIVE_BUYING:
                        stream.setOrderSubType(4);
                        break;
                    case MULTIPLE_USER:
                        stream.setOrderSubType(3);
                        break;
                    default:
                }
                break;
            case AMOUNT_OF_RECHARGE:
                stream.setOrderType(3);
                if (Objects.equals(OrderSubType.STORED_CARD_RECHARGE.getType(), orderSubType)) {
                    stream.setOrderSubType(5);
                } else {
                    stream.setOrderSubType(0);
                }
                break;
            case OFFLINE:
                stream.setOrderType(2);
                break;
            case COUPON:
                if (Objects.equals(OrderSubType.COUPONS_OF_GROUP.getType(), orderSubType)) {
                    stream.setOrderType(12);
                    stream.setOrderSubType(0);
                } else if (Objects.equals(OrderSubType.DY_COUPON.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(0);
                } else if (Objects.equals(OrderSubType.COUNT_CARD.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(1);
                } else if (Objects.equals(OrderSubType.DY_WALLET.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(2);
                } else if (Objects.equals(OrderSubType.WE_CHAT_VIDEO.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(3);
                } else if (Objects.equals(OrderSubType.COUPON.getType(), orderSubType)) {
                    stream.setOrderType(6);
                    stream.setOrderSubType(0);
                }
                break;
            case GIFT_CARD:
                if (Objects.equals(OrderSubType.PHY_AMOUNT_CARD.getType(), orderSubType)) {
                    stream.setOrderType(4);
                    stream.setOrderSubType(8);
                } else {
                    stream.setOrderType(4);
                    stream.setOrderSubType(0);
                }
                break;
            case MEMBERSHIP_CARD:
                stream.setOrderType(5);
                stream.setOrderSubType(0);
                break;
            case POINTS_OF_E_SHOP:
                stream.setOrderType(7);
                stream.setOrderSubType(0);
            case ACTIVITY:
                if (Objects.equals(OrderSubType.BLIND_BOX_LOTTERY_DRAW.getType(), orderSubType)) {
                    stream.setOrderType(60);
                    stream.setOrderSubType(0);
                } else if (Objects.equals(OrderSubType.ACTIVITY_BOOKING.getType(), orderSubType)) {
                    stream.setOrderType(91);
                    stream.setOrderSubType(0);
                }
                break;
            default:
        }
    }

    private void reverseCatering(Integer bizType, DataStream stream, Integer oldPerfType, Integer perfStatus, String performancePlatform) {
        Integer orderType = stream.getOrderType();
        Integer orderSubType = stream.getOrderSubType();
        OrderType orderTypeRoute = OrderType.get(orderType);

        switch (orderTypeRoute) {
            case IN_STORE:
                mapping(stream, perfStatus, performancePlatform, bizType);
                break;
            case OFFLINE:
                if (Objects.equals(OrderSubType.PAY_CODE.getType(), stream.getOrderSubType())) {
                    stream.setOrderType(7);
                    stream.setOrderSubType(0);
                } else {
                    stream.setOrderType(4);
                    stream.setOrderSubType(0);
                }
                break;
            case E_SHOP:
                stream.setOrderType(14);
                stream.setOrderSubType(0);
                if (Objects.equals(1, stream.getPerformanceType())) {
                    stream.setPerformanceType(5);
                }
                break;
            case ACTIVITY:
                stream.setOrderType(40);

                if (Objects.equals(OrderSubType.BLIND_BOX_LOTTERY_DRAW.getType(), orderSubType)) {
                    stream.setOrderSubType(60);
                } else if (Objects.equals(OrderSubType.DRAW_LOTTERY_ACTIVITY.getType(), orderSubType)) {
                    stream.setOrderSubType(71);
                } else if (Objects.equals(OrderSubType.EXCHANGE_GOODS.getType(), orderSubType)) {
                    stream.setOrderSubType(70);
                }
                if (Objects.equals(1, oldPerfType)) {
                    stream.setPerformanceType(5);
                }
                break;
            case COUPON:
                if (Objects.equals(OrderSubType.COUPONS_OF_GROUP.getType(), orderSubType)) {
                    stream.setOrderType(12);
                    stream.setOrderSubType(0);
                } else if (Objects.equals(OrderSubType.ALI_PAY_GROUP_COUPON.getType(), orderSubType)) {
                    stream.setOrderType(8);
                    stream.setOrderSubType(15);
                } else if (Objects.equals(OrderSubType.DY_COUPON.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(0);
                } else if (Objects.equals(OrderSubType.COUNT_CARD.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(1);
                } else if (Objects.equals(OrderSubType.DY_WALLET.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(2);
                } else if (Objects.equals(OrderSubType.WE_CHAT_VIDEO.getType(), orderSubType)) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(3);
                } else {
                    stream.setOrderType(8);
                    stream.setOrderSubType(0);
                }
                break;
            case GIFT_CARD:
                if (Objects.equals(OrderSource.DY.getType(), stream.getSource())) {
                    stream.setOrderType(30);
                    stream.setOrderSubType(2);
                } else {
                    stream.setOrderType(10);
                    stream.setOrderSubType(0);
                }
                break;
            case MEMBERSHIP_CARD:
                stream.setOrderType(13);
                stream.setOrderSubType(0);
                break;
            case AMOUNT_OF_RECHARGE:
                stream.setOrderType(5);
                stream.setOrderSubType(0);
                break;
            case DEPOSIT:
                if (bizType == 7) {
                    stream.setOrderType(16);
                    stream.setOrderSubType(0);
                }
                break;
            case POINTS_OF_E_SHOP:
                if (Objects.equals(OrderSubType.POINTS_COLL_CASH.getType(), orderSubType)) {
                    stream.setOrderType(11);
                    stream.setOrderSubType(0);
                } else if (Objects.equals(OrderSubType.GENERIC.getType(), orderSubType)) {
                    stream.setOrderType(20);
                    stream.setOrderSubType(29);
                    if (Objects.equals(1, stream.getPerformanceType())) {
                        stream.setPerformanceType(5);
                    }
                }
                break;
            default:
        }
    }

    private void mapping(DataStream stream, Integer perfStatus, String performancePlatform, Integer bizType) {
        PerformanceType type = PerformanceType.get(stream.getPerformanceType());
        if (type != null) {
            switch (type) {
                case EAT_ON_SITE:
                    stream.setOrderType(1);
                    stream.setPerformanceType(0);
                    break;
                case SELF_TAKE:
                    stream.setOrderType(2);
                    stream.setPerformanceType(0);
                    break;
                case IN_CITY_DELIVERY:
                    stream.setOrderType(3);
                    stream.setPerformanceType(0);
                    if (Objects.equals(1, perfStatus) && StringUtils.isNotBlank(performancePlatform)) {
                        if (StringUtils.equals("99", performancePlatform)) {
                            stream.setPerformancePlatform(PerformancePlatform.SELLER.getDesc());
                        }
                        if (!StringUtils.equals("99", performancePlatform)) {
                            Integer platform = Integer.valueOf(MapperFactory.reversePlatform(bizType, performancePlatform));
                            stream.setPerformanceType(platform);
                            DeliveryPlatformEnum byCode = DeliveryPlatformEnum.findByCode(platform);
                            if (byCode != null) {
                                stream.setPerformancePlatform(byCode.getName());
                            }
                        }
                    }
                    break;
                case TAKEAWAY_SELF_TAKE:
                    stream.setOrderType(35);
                    stream.setPerformanceType(0);
                    break;
                default:
            }
        }
    }
}
