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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dao.OrderRefundDao;
import com.liquidnet.service.kylin.dto.param.RefundCallbackParam;
import com.liquidnet.service.kylin.dto.vo.KylinOrderRefundsVo;
import com.liquidnet.service.kylin.entity.KylinOrderRefunds;
import com.liquidnet.service.kylin.entity.KylinOrderTickets;
import com.liquidnet.service.kylin.mapper.KylinOrderRefundsMapper;
import com.liquidnet.service.kylin.mapper.KylinOrderTicketsMapper;
import com.liquidnet.service.kylin.service.IKylinOrderRefundsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 订单退款表 服务实现类
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-26
 */
@Slf4j
@Service
public class KylinOrderRefundsServiceImpl extends ServiceImpl<KylinOrderRefundsMapper, KylinOrderRefunds> implements IKylinOrderRefundsService {
    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    private KylinRefundsStatusServiceImpl kylinRefundsStatusServiceImpl;

    @Autowired
    private KylinOrderRefundsMapper kylinOrderRefundsMapper;

    public Boolean refundApply(String orderTicketsId, String reason, String orderRefundBatchesId, String refundData) throws Exception {
        int count = 0;
        count = kylinOrderTicketsMapper.selectCount(
                new UpdateWrapper<KylinOrderTickets>().eq("order_tickets_id", orderTicketsId).eq("coupon_type2", "full")
        );
        if (count > 0) {
            throw new Exception("使用满减券 暂不能退款");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefunding(orderTicketsId, refundData, reason, orderRefundBatchesId);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundCancel(List orderRefundsIdList) throws Exception {
        Integer[] orderRefundStatus = {KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("type", KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY)
                        .in("order_refunds_id", orderRefundsIdList)
                        .in("status", orderRefundStatus)
        );
        if (orderRefundsIdList.size() != refundList.size()) {
            throw new Exception("订单需未审核、已驳回、已回绝，非自动退款订单");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefundCancel(refundList);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundReapply(List orderRefundsIdList) throws Exception {
        Integer[] orderRefundStatus = {KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("type", KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY)
                        .in("order_refunds_id", orderRefundsIdList)
                        .in("status", orderRefundStatus)
        );
        if (orderRefundsIdList.size() != refundList.size()) {
            throw new Exception("订单需已驳回、已回绝");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefundReapply(refundList);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundApproved(List orderRefundsIdList, String reject) throws Exception {
        Integer[] orderRefundStatus = {KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_REJECT, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("type", KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY)
                        .in("order_refunds_id", orderRefundsIdList)
                        .in("status", orderRefundStatus)
        );
        if (orderRefundsIdList.size() != refundList.size()) {
            throw new Exception("订单需未审核、已驳回、已回绝，请检查订单状态");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefundApproved(refundList, reject);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundReject(List orderRefundsIdList, String reject) throws Exception {
        Integer[] orderRefundStatus = {KylinTableStatusConst.ORDER_REFUND_STATUS_APPLY, KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_REFUSE};
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("type", KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY)
                        .in("order_refunds_id", orderRefundsIdList)
                        .in("status", orderRefundStatus)
        );
        if (orderRefundsIdList.size() != refundList.size()) {
            throw new Exception("订单需未审核、已审核、已回绝，请检查订单状态");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefundReject(refundList, reject);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundUnfilled(List orderRefundsIdList, String refuse) throws Exception {
        Integer[] orderRefundStatus = {KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR};
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("type", KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY)
                        .in("order_refunds_id", orderRefundsIdList)
                        .in("status", orderRefundStatus)
        );
        if (orderRefundsIdList.size() != refundList.size()) {
            throw new Exception("订单需已审核、退款失败，请检查订单状态");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefundUnfilled(refundList, refuse);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundRefuse(List orderRefundsIdList, String refuse) throws Exception {
        Integer[] orderRefundStatus = {KylinTableStatusConst.ORDER_REFUND_STATUS_APPROVED, KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR};
        List<KylinOrderRefunds> refundList = kylinOrderRefundsMapper.selectList(
                new QueryWrapper<KylinOrderRefunds>()
                        .eq("type", KylinTableStatusConst.ORDER_REFUND_TYPE_APPLY)
                        .in("order_refunds_id", orderRefundsIdList)
                        .in("status", orderRefundStatus)
        );
        if (orderRefundsIdList.size() != refundList.size()) {
            throw new Exception("订单需已审核、退款失败，请检查订单状态");
        }

        boolean res = kylinRefundsStatusServiceImpl.orderTicketRefundRefuse(refundList, refuse);
        if (res) {
            return true;
        } else {
            return false;
        }
    }

    public Boolean refundCompleted(Integer orderRefundsId) {
        return false;
    }

    public KylinOrderRefundsVo detail(String orderRefundId) {
        KylinOrderRefunds data = kylinOrderRefundsMapper.selectOne(
                new UpdateWrapper<KylinOrderRefunds>()
                        .eq("order_refunds_id", orderRefundId)
        );
        KylinOrderRefundsVo kylinOrderRefundsVo = new KylinOrderRefundsVo();
        BeanUtils.copyProperties(data, kylinOrderRefundsVo);

        return kylinOrderRefundsVo;
    }

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

    public String refundCallback(RefundCallbackParam refundCallbackParam) {
        KylinOrderRefunds refundInfo = kylinOrderRefundsMapper.selectOne(
                new UpdateWrapper<KylinOrderRefunds>()
                        .eq("order_refund_code", refundCallbackParam.getOrder_refund_code())
        );
        if (refundInfo == null) {
            log.info("Failed:{}.RefundController refundCallback: 退款订单查询失败，编号{}", "KylinOrderRefundsServiceImplRefundCallback", refundCallbackParam.getOrder_refund_code());
            return "fail";
        }
        if (refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_CANCEL) {
            log.info("Failed:{}.RefundController refundCallback: 退款订单已取消，编号{}", "KylinOrderRefundsServiceImplRefundCallback", refundCallbackParam.getOrder_refund_code());
            return "fail";
        }
        if (refundInfo.getStatus() == KylinTableStatusConst.ORDER_REFUND_STATUS_REFUNDED) {
            log.info("Failed:{}.RefundController refundCallback: 退款订单已退款，编号{}", "KylinOrderRefundsServiceImplRefundCallback", refundCallbackParam.getOrder_refund_code());
            return "success";
        }

        Integer status = refundCallbackParam.getStatus();
        if (1 == status) { // 退款成功
            boolean res = kylinRefundsStatusServiceImpl.orderTicketRefunded(refundCallbackParam, refundInfo);
            if (res) {
                return "success";
            } else {
                return "fail";
            }
        }
        if (0 == status) { // 退款失败
            KylinOrderRefunds kylinOrderRefunds = new KylinOrderRefunds();
            kylinOrderRefunds.setStatus(KylinTableStatusConst.ORDER_REFUND_STATUS_ERROR);
            kylinOrderRefunds.setRefundCode(refundCallbackParam.getRefund_code());
            kylinOrderRefunds.setRefundType(refundCallbackParam.getRefund_type());
            kylinOrderRefunds.setRefundId(refundCallbackParam.getRefund_id());
            kylinOrderRefunds.setRefundAt(refundCallbackParam.getRefund_at());
            kylinOrderRefunds.setRefundError(refundCallbackParam.getRefund_error());

            kylinOrderRefundsMapper.update(
                    kylinOrderRefunds,
                    new UpdateWrapper<KylinOrderRefunds>().eq("order_refund_code", refundCallbackParam.getOrder_refund_code())
            );
        }
        return "success";
    }

}