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

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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.dao.OrderRefundBatchDao;
import com.liquidnet.service.kylin.dto.vo.KylinOrderRefundBatchesVo;
import com.liquidnet.service.kylin.dto.vo.KylinPerformanceVo;
import com.liquidnet.service.kylin.entity.KylinOrderRefundBatches;
import com.liquidnet.service.kylin.mapper.KylinOrderRefundBatchesMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/**
 * <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 KylinOrderRefundBatchesMapper kylinOrderRefundBatchesMapper;

    @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);

        KylinOrderRefundBatches refundBatchesInfo = kylinOrderRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinOrderRefundBatches>().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();

            KylinOrderRefundBatches createData = new KylinOrderRefundBatches();
            createData.setRefundBatchId(refundBatchId);
            createData.setStatus(KylinTableStatusConst.STATUS_APPLY);

            int resNum = kylinOrderRefundBatchesMapper.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};
        KylinOrderRefundBatches refundBatchesInfo = kylinOrderRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinOrderRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

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

            KylinOrderRefundBatches params = new KylinOrderRefundBatches();
            params.setStatus(KylinTableStatusConst.STATUS_APPLY);
            kylinOrderRefundBatchesMapper.update(params, new UpdateWrapper<KylinOrderRefundBatches>().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};
        KylinOrderRefundBatches refundBatchesInfo = kylinOrderRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinOrderRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

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

            KylinOrderRefundBatches params = new KylinOrderRefundBatches();
            params.setStatus(KylinTableStatusConst.STATUS_CANCEL);
            kylinOrderRefundBatchesMapper.update(params, new UpdateWrapper<KylinOrderRefundBatches>().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};
        KylinOrderRefundBatches refundBatchesInfo = kylinOrderRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinOrderRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

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

            KylinOrderRefundBatches params = new KylinOrderRefundBatches();
            params.setStatus(batchStatus);
            kylinOrderRefundBatchesMapper.update(params, new UpdateWrapper<KylinOrderRefundBatches>().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};
        KylinOrderRefundBatches refundBatchesInfo = kylinOrderRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinOrderRefundBatches>().eq("refund_batch_id", refundBatchId).in("status", paymentTypeAlipayArray)
        );
        if (!refundBatchesInfo.getRefundBatchId().isEmpty()) {

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

            KylinOrderRefundBatches params = new KylinOrderRefundBatches();
            params.setStatus(batchStatus);
            params.setExecutorAt(LocalDateTime.now());
            kylinOrderRefundBatchesMapper.update(params, new UpdateWrapper<KylinOrderRefundBatches>().eq("refund_batch_id", refundBatchId));

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

    public KylinOrderRefundBatchesVo detail(String orderRefundId) {
        KylinOrderRefundBatches data = kylinOrderRefundBatchesMapper.selectOne(
                new UpdateWrapper<KylinOrderRefundBatches>()
                        .eq("order_refunds_id", orderRefundId)
        );
        KylinOrderRefundBatchesVo kylinOrderRefundBatchesVo = new KylinOrderRefundBatchesVo();
        BeanUtils.copyProperties(data, kylinOrderRefundBatchesVo);

        return kylinOrderRefundBatchesVo;
    }

    public PageInfo<OrderRefundBatchDao> refundList(Integer page, Integer size) {
        PageInfo<OrderRefundBatchDao> pageInfoTmp = null;
        try {
            PageHelper.startPage(page, size);
            List<OrderRefundBatchDao> voList = kylinOrderRefundBatchesMapper.misRefundBatchList();
            pageInfoTmp = new PageInfo(voList);
        } catch (Exception e) {
            return null;
        }
        return pageInfoTmp;
    }

}
