package com.liquidnet.client.admin.zhengzai.kylin.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dto.param.RefundApplyParam;
import com.liquidnet.service.kylin.dto.param.RefundBatchApplyParam;
import com.liquidnet.service.kylin.entity.KylinOrderRefunds;
import com.liquidnet.service.kylin.entity.KylinOrderTicketEntities;
import com.liquidnet.service.kylin.entity.KylinOrderTickets;
import com.liquidnet.service.kylin.mapper.KylinOrderRefundsMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketEntitiesMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台退款 服务实现类
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-25 19:50 下午
 */
@Service
public class KylinRefundExecuteServiceImpl {

    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    private KylinOrderRefundsMapper kylinOrderRefundsMapper;

    @Autowired
    private KylinOrderTicketEntitiesMapper kylinOrderTicketEntitiesMapper;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    private KylinOrderRefundsServiceImpl kylinOrderRefundsServiceImpl;

    @Async
    public void refundBatchApply(String targetId, String refundBatchId, String reason) throws Exception {
        RefundApplyParam refundApplyParam = new RefundApplyParam();
        int count;
        int limitNum = 100;
        int mid = 0;
        do {
            List<KylinOrderTickets> orderList = kylinOrderTicketsMapper.getOrderList(targetId, mid, limitNum);

            for (KylinOrderTickets order : orderList) {
                List<KylinOrderTicketEntities> entitiesList = kylinOrderTicketEntitiesMapper.selectList(
                        new UpdateWrapper<KylinOrderTicketEntities>().eq("order_id", order.getOrderTicketsId())
                                .eq("is_payment", "yes")
                );
                List<String> ticketEntityIds = entitiesList.stream().map(KylinOrderTicketEntities -> KylinOrderTicketEntities.getOrderTicketEntitiesId()).collect(Collectors.toList());
                // 请求php接口
                refundApplyParam.setOrderRefundBatchesId(refundBatchId);
                refundApplyParam.setReason(reason);
                refundApplyParam.setOrderTicketsId(order.getOrderTicketsId());
                refundApplyParam.setTicketEntityIds(ticketEntityIds);
                refundApplyParam.setRefundPriceExpress(order.getPriceExpress().doubleValue());
                Boolean res = kylinOrderRefundsServiceImpl.refundApply(refundApplyParam);
            }

            count = orderList.size();
            KylinOrderTickets lastInfo = orderList.get(count - 1);
            mid = lastInfo.getMid();
        } while (count >= limitNum);
    }

    @Async
    public void refundBatchStatus(RefundBatchApplyParam refundBatchApplyParam, String type) throws Exception {
        String refundBatchId = refundBatchApplyParam.getRefundBatchId();
        Integer status = refundBatchApplyParam.getStatus();
        // 处理查询订单状态
        Integer[] whereStatus = {};
        Integer whereType = KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY;
        switch (type) {
            case "reapply":
                whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
                break;
            case "cancel":
                whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
                break;
            case "review":
                if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED) { // 通过申请
                    whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
                }
                if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT) { // 驳回申请
                    whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
                }
                break;
            case "execute":
                if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_UNFILLED) { // 执行退款
                    whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR};
                }
                if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE) { // 拒绝退款
                    whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR};
                }
                break;
            default:
                throw new Exception("type异常，无法操作");
        }

        int count;
        int limitNum = 1;
        int mid = 0;
        do {
            List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.getRefundList(whereType, refundBatchId, whereStatus, mid, limitNum);

            List<String> refundIds = null;
            if (!refundList.isEmpty()) {
                refundIds = refundList.stream().map(KylinOrderRefunds -> KylinOrderRefunds.getOrderRefundsId()).collect(Collectors.toList());

                RefundApplyParam refundApplyParam = new RefundApplyParam();
                refundApplyParam.setIds(refundIds);
                Boolean res = null;

                switch (type) {
                    case "reapply":
                        res = kylinOrderRefundsServiceImpl.refundReapply(refundApplyParam);
                        break;
                    case "cancel":
                        res = kylinOrderRefundsServiceImpl.refundCancel(refundApplyParam);
                        break;
                    case "review":
                        if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED) { // 通过申请
                            res = kylinOrderRefundsServiceImpl.refundApproved(refundApplyParam);
                        }
                        if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT) { // 驳回申请
                            res = kylinOrderRefundsServiceImpl.refundReject(refundApplyParam);
                        }
                        break;
                    case "execute":
                        if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_UNFILLED) { // 执行退款
                            res = kylinOrderRefundsServiceImpl.refundUnfilled(refundApplyParam);
                        }
                        if (status == KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE) { // 拒绝退款
                            res = kylinOrderRefundsServiceImpl.refundRefuse(refundApplyParam);
                        }
                        break;
                    default:
                        throw new Exception("type异常，无法操作");
                }
            }

            count = refundList.size();
            KylinOrderRefunds lastInfo = refundList.get(count - 1);
            mid = lastInfo.getMid();
        } while (count >= limitNum);
    }

}
