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

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dto.vo.KylinPerformanceVo;
import com.liquidnet.service.kylin.entity.KylinRefundBatches;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import com.liquidnet.service.kylin.mapper.KylinRefundBatchesMapper;
import com.liquidnet.service.kylin.service.IKylinRefundBatchesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;

/**
 * <p>
 * 后台退款 服务实现类
 * status 0待付款，1已付款，2已关闭，3正在退款，4已退款, 5待关闭
 * pay_status 支付状态:0未支付 1已支付 2支付失败等
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-25 11:26 上午
 */
@Service
public class KylinRefundPerformancesAdminServiceImpl {

    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    private KylinRefundBatchesMapper kylinRefundBatchesMapper;

    @Autowired
    private KylinRefundExecuteServiceImpl kylinRefundExecuteServiceImpl;

    @Autowired
    RedisUtil redisUtil;

    public Boolean refundBatchApply(String targetId, Integer targetType, Integer authId, String authName, HashMap<String, Object> OtherParam) throws Exception {
        HashMap<String, Object> priceNum = kylinOrderTicketsMapper.getPriceNum(targetId);
        Double totalPrice = (Double) priceNum.get("total_price");
        Integer totalNum = (Integer) priceNum.get("total_num");
        if (totalPrice < 0 || totalNum < 0) throw new Exception("当前演出暂无需要退款的订单，请确认后重试！");

        // 汇总退款
        String[] paymentTypeAlipayArray = {"APPALIPAY", "WAPALIPAY", "alipay"};
        double totalRefundAlipay = kylinOrderTicketsMapper.getTotalPrice(targetId, "price_actual", paymentTypeAlipayArray);
        String[] paymentTypeWepayArray = {"APPWEPAY", "APPLETWEPAY", "WAPWEPAY", "JSWEPAY", "wepay"};
        double totalRefundWepay = kylinOrderTicketsMapper.getTotalPrice(targetId, "price_actual", paymentTypeWepayArray);
        double totalPriceExpressAlipay = kylinOrderTicketsMapper.getTotalPrice(targetId, "price_express", paymentTypeAlipayArray);
        double totalPriceExpressWepay = kylinOrderTicketsMapper.getTotalPrice(targetId, "price_express", paymentTypeWepayArray);

        KylinRefundBatches refundBatchesInfo = kylinRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinRefundBatches>().eq("target_id", targetId).eq("target_type", targetType).orderByDesc("refund_batch_id")
        );
        if (refundBatchesInfo.getRefundBatchId().isEmpty() || refundBatchesInfo.getStatus() == KylinTableStatusConst.STATUS_CANCEL || refundBatchesInfo.getStatus() == KylinTableStatusConst.STATUS_FINANCE_ADOPT) {

            // 添加演出退款记录
            KylinPerformanceVo performancesInfo = (KylinPerformanceVo) redisUtil.hget(KylinRedisConst.PERFORMANCES, targetId);
            String refundBatchId = IDGenerator.nextSnowId().toString();

            KylinRefundBatches createData = new KylinRefundBatches();
            createData.setRefundBatchId(refundBatchId);
            createData.setTargetTitle(performancesInfo.getTitle());
            createData.setTotalPrice(BigDecimal.valueOf(totalPrice));
            createData.setTotalNum(totalNum);
            createData.setTotalRefundAlipay(BigDecimal.valueOf(totalRefundAlipay));
            createData.setTotalRefundWepay(BigDecimal.valueOf(totalRefundWepay));
            createData.setTotalPriceExpressAlipay(BigDecimal.valueOf(totalPriceExpressAlipay));
            createData.setTotalPriceExpressWepay(BigDecimal.valueOf(totalPriceExpressWepay));
            createData.setApplicantId(authId);
            createData.setApplicantName(authName);
            createData.setStatus(KylinTableStatusConst.STATUS_APPLY);
            createData.setApplicantAt(LocalDateTime.now());

            int resNum = kylinRefundBatchesMapper.insert(createData);
            if (resNum > 0) {
                // 开始执行批量提交审核 分批处理退款申请
                kylinRefundExecuteServiceImpl.refundBatchApply(targetId, refundBatchId, OtherParam);
                return true;
            } else {
                return false;
            }
        } else {
            throw new Exception("该演出已经提交过申请，请刷新申请列表查看");
        }
    }

    public Boolean refundBatchReapply(String refundBatchId, String remark, HashMap<String, Object> otherParam) throws Exception {
        Integer[] paymentTypeAlipayArray = {KylinTableStatusConst.STATUS_OPERATE_REJECT, KylinTableStatusConst.STATUS_FINANCE_REJECT};
        KylinRefundBatches refundBatchesInfo = kylinRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

            // 开始执行批量提交审核 分批处理退款申请
            kylinRefundExecuteServiceImpl.refundBatchStatus(refundBatchId, otherParam);

            KylinRefundBatches params = new KylinRefundBatches();
            params.setStatus(KylinTableStatusConst.STATUS_APPLY);
            params.setRemark(remark);
            kylinRefundBatchesMapper.update(params, new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId));

            return true;
        } else {
            throw new Exception("当前状态下不允许此操作");
        }
    }

    public Boolean refundBatchCancel(String refundBatchId, HashMap<String, Object> otherParam) throws Exception {
        Integer[] paymentTypeAlipayArray = {KylinTableStatusConst.STATUS_APPLY, KylinTableStatusConst.STATUS_OPERATE_REJECT, KylinTableStatusConst.STATUS_OPERATE_ADOPT, KylinTableStatusConst.STATUS_FINANCE_REJECT};
        KylinRefundBatches refundBatchesInfo = kylinRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

            // 开始执行批量提交审核 分批处理退款申请
            kylinRefundExecuteServiceImpl.refundBatchStatus(refundBatchId, otherParam);

            KylinRefundBatches params = new KylinRefundBatches();
            params.setStatus(KylinTableStatusConst.STATUS_CANCEL);
            kylinRefundBatchesMapper.update(params, new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId));

            return true;
        } else {
            throw new Exception("当前状态下不允许此操作");
        }
    }

    public Boolean refundBatchReview(String refundBatchId, HashMap<String, Object> otherParam) throws Exception {
        Integer batchStatus = (Integer) otherParam.get("status");
        Integer updateStatus = 0;
        if (KylinTableStatusConst.STATUS_OPERATE_REJECT == batchStatus) {// 驳回
            updateStatus = KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT;
        } else if (KylinTableStatusConst.STATUS_OPERATE_ADOPT == batchStatus) {// 通过
            updateStatus = KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED;
        }
        Integer[] paymentTypeAlipayArray = {KylinTableStatusConst.STATUS_APPLY};
        KylinRefundBatches refundBatchesInfo = kylinRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

            // 开始执行批量提交审核 分批处理退款申请
            otherParam.put("status", updateStatus);
            kylinRefundExecuteServiceImpl.refundBatchStatus(refundBatchId, otherParam);

            KylinRefundBatches params = new KylinRefundBatches();
            params.setStatus(batchStatus);
            params.setReject((String) otherParam.get("reject"));
            params.setAuditorId(2);
            params.setAuditorName("2222");
            params.setAuditorAt(LocalDateTime.now());
            kylinRefundBatchesMapper.update(params, new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId));

            return true;
        } else {
            throw new Exception("当前状态下不允许此操作");
        }
    }

    public Boolean refundBatchExecute(String refundBatchId, HashMap<String, Object> otherParam) throws Exception {
        Integer batchStatus = (Integer) otherParam.get("status");
        Integer updateStatus = 0;
        if (KylinTableStatusConst.STATUS_FINANCE_REJECT == batchStatus) {// 驳回
            updateStatus = KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE;
        } else if (KylinTableStatusConst.STATUS_FINANCE_ADOPT == batchStatus) {// 通过
            updateStatus = KylinTableStatusConst.ORDER_REFUND_STATUS_UNFILLED;
        }
        Integer[] paymentTypeAlipayArray = {KylinTableStatusConst.STATUS_APPLY};
        KylinRefundBatches refundBatchesInfo = kylinRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

            // 开始执行批量提交审核 分批处理退款申请
            otherParam.put("status", updateStatus);
            kylinRefundExecuteServiceImpl.refundBatchStatus(refundBatchId, otherParam);

            KylinRefundBatches params = new KylinRefundBatches();
            params.setStatus(batchStatus);
            params.setRefuse((String) otherParam.get("refuse"));
            params.setExecutorId(2);
            params.setExecutorName("2222");
            params.setExecutorAt(LocalDateTime.now());
            kylinRefundBatchesMapper.update(params, new UpdateWrapper<KylinRefundBatches>().eq("refund_batch_id", refundBatchId));

            return true;
        } else {
            throw new Exception("当前状态下不允许此操作");
        }
    }

}
