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.base.ResponseDto;
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;

    public void refundBatchApply(String targetId, String refundBatchId, String reason) {
        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", 1)
                );
                List<String> ticketEntityIds = entitiesList.stream().map(KylinOrderTicketEntities -> KylinOrderTicketEntities.getOrderTicketEntitiesId()).collect(Collectors.toList());

                refundApplyParam.setOrderRefundBatchesId(refundBatchId);
                refundApplyParam.setReason(reason);
                refundApplyParam.setOrderTicketsId(order.getOrderTicketsId());
                refundApplyParam.setTicketEntityIds(ticketEntityIds);
                if (order.getPriceExpress() != null) {
                    refundApplyParam.setRefundPriceExpress(order.getPriceExpress().doubleValue());
                }
                ResponseDto res = kylinOrderRefundsServiceImpl.refundApply(refundApplyParam);
            }

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

    public void refundBatchStatus(RefundBatchApplyParam refundBatchApplyParam, String type) throws Exception {
        String refundBatchId = refundBatchApplyParam.getRefundBatchId();
        Integer status = refundBatchApplyParam.getRefundStatus();
        // 处理查询订单状态
        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) { // 通过申请
                    type = "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) { // 驳回申请
                    type = "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) { // 执行退款
                    type = "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) { // 拒绝退款
                    type = "refuse";
                    whereStatus = new Integer[]{KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR};
                }
                break;
            default:
                throw new Exception("type异常，无法操作");
        }

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

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

                RefundApplyParam refundApplyParam = new RefundApplyParam();
                refundApplyParam.setIds(refundIds);
                refundApplyParam.setType(type);
                if (null != refundBatchApplyParam.getRefuse()) {
                    refundApplyParam.setRefuse(refundBatchApplyParam.getRefuse());
                }
                if (null != refundBatchApplyParam.getReject()) {
                    refundApplyParam.setReject(refundBatchApplyParam.getReject());
                }
                ResponseDto res = kylinOrderRefundsServiceImpl.refundCheckStatus(refundApplyParam);
            }

            count = refundList.size();
            if (count > 0){
                KylinOrderRefunds lastInfo = refundList.get(count - 1);
                if (lastInfo != null) {
                    mid = lastInfo.getMid();
                }
            }
        } while (count >= limitNum);
    }

}
