package cn.freemud.handler;

import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.entities.db.db2.RefundOverOrder;
import cn.freemud.entities.dto.delivery.GetFilterPartnerResponse;
import cn.freemud.entities.dto.delivery.PartnerFilterResponse;
import cn.freemud.entities.dto.openplatform.OrderGetPartnerRequest;
import cn.freemud.entities.vo.OrderCountRequestVo;
import cn.freemud.entities.vo.OrderRefundVo;
import cn.freemud.entities.vo.SendOrderCountsMsg;
import cn.freemud.enums.CouponOrderRefundFailTypeEnum;
import cn.freemud.enums.CouponOrderRefundStatusEnum;
import cn.freemud.enums.ResponseResult;
import cn.freemud.manager.RefundOverOrderManager;
import cn.freemud.manager.db2.dao.RefundOverOrderDao;
import cn.freemud.service.Orderservice;
import cn.freemud.service.thirdparty.EcologyAdminApplicationClient;
import cn.freemud.utils.AppLogUtil;
import cn.freemud.utils.ExceptionUtils;
import com.alibaba.fastjson.JSON;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.response.OrderCountResp;
import com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;


/**
 * @author : xh.Z
 * @email : fisherman0510@163.com
 * @Date : 2021/4/26 下午8:27
 * @description :
 */
@Component
public class CouponOrderAutoRefundHandler {

    @Autowired
    private Orderservice orderservice;

    @Autowired
    private RefundOverOrderManager refundOverOrderManager;

    private ExecutorService executor = Executors.newFixedThreadPool(5);

    public ReturnT<String> execute(String param) throws Exception {

        long now = System.currentTimeMillis();
        Date nowDate = new Date(now);
        String nowDay = DateUtil.convert2String(nowDate, "yyyy-MM-dd");
        Date todayStart = DateUtil.convert2Date(nowDay+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
        Date today1 = DateUtil.addHours(todayStart, 1);
        Date today6 = DateUtil.addHours(todayStart, 6);
        Date today23 = DateUtil.addHours(todayStart, 23);
        if(nowDate.after(today23) || nowDate.before(today1)) {
            ApiLog.infoMessage("23点到1点不执行： "+now);
            return ReturnT.SUCCESS;
        }
        int num = 200;
        boolean isBeforeDawn = nowDate.after(today1) && nowDate.before(today6);
        if(isBeforeDawn) {
            num = 500;
        }

        List<RefundOverOrder> refundOverOrderList = refundOverOrderManager.selectBatch(num);
        if(CollectionUtils.isEmpty(refundOverOrderList)) {
            ApiLog.infoMessage("未查询到需要退款的买券订单");
            return ReturnT.SUCCESS;
        }

        executor.execute(() -> {
            ApiLog.infoMessage("开始自动给买券订单过期券退款 ： " + JSON.toJSONString(refundOverOrderList));

            for(RefundOverOrder refundOverOrder : refundOverOrderList) {
                RefundOverOrder refundOverOrderUpdate = new RefundOverOrder();
                refundOverOrderUpdate.setRefundId(refundOverOrder.getRefundId());
                try {
                    OrderRefundVo orderRefundVo = new OrderRefundVo();
                    orderRefundVo.setOid(refundOverOrder.getRefundOrderCode());
                    orderRefundVo.setReason("券过期自动退款");
                    orderRefundVo.setRemarks("券过期自动退款");
                    BaseResponse baseResponse = orderservice.couponOrderRefund(orderRefundVo, 1);
                    if(ResponseResult.SUCCESS.getCode().equals(baseResponse.getCode())) {
                        refundOverOrderUpdate.setRefundStatus(CouponOrderRefundStatusEnum.REFUNDED.getCode());
                        refundOverOrderUpdate.setRefundFail(CouponOrderRefundFailTypeEnum.SUCCESS.getCode());
                        refundOverOrderUpdate.setRefundDesc("成功");
                    } else if(ResponseResult.COUPON_CANCEL_FAIL.getCode().equals(baseResponse.getCode())) {
                        refundOverOrderUpdate.setRefundStatus(CouponOrderRefundStatusEnum.NOT_NEED_REFUND.getCode());
                        refundOverOrderUpdate.setRefundFail(CouponOrderRefundFailTypeEnum.COUPON_PROCESS_FAIL.getCode());
                        refundOverOrderUpdate.setRefundDesc(JSON.toJSONString(baseResponse));
                    } else if(ResponseResult.COUPON_ORDER_VERIFY_FAIL.getCode().equals(baseResponse.getCode())) {
                        refundOverOrderUpdate.setRefundStatus(CouponOrderRefundStatusEnum.REFUND_FAILED.getCode());
                        refundOverOrderUpdate.setRefundFail(CouponOrderRefundFailTypeEnum.ORDER_VERIFY_FAIL.getCode());
                        refundOverOrderUpdate.setRefundDesc(JSON.toJSONString(baseResponse));
                    } else if(ResponseResult.ORDER__ERRORREFUND.getCode().equals(baseResponse.getCode())) {
                        refundOverOrderUpdate.setRefundStatus(CouponOrderRefundStatusEnum.REFUND_FAILED.getCode());
                        refundOverOrderUpdate.setRefundFail(CouponOrderRefundFailTypeEnum.ORDER_VERIFY_FAIL.getCode());
                        refundOverOrderUpdate.setRefundDesc(JSON.toJSONString(baseResponse));
                    } else {
                        refundOverOrderUpdate.setRefundStatus(CouponOrderRefundStatusEnum.REFUND_FAILED.getCode());
                        refundOverOrderUpdate.setRefundFail(CouponOrderRefundFailTypeEnum.OTHER.getCode());
                        refundOverOrderUpdate.setRefundDesc(JSON.toJSONString(baseResponse));
                    }
                    refundOverOrderManager.update(refundOverOrder);
                    if(isBeforeDawn) {
                        Thread.sleep(1000);
                    }
                } catch (Exception e) {
                    refundOverOrderUpdate.setRefundStatus(CouponOrderRefundStatusEnum.REFUND_FAILED.getCode());
                    refundOverOrderUpdate.setRefundFail(CouponOrderRefundFailTypeEnum.OTHER.getCode());
                    refundOverOrderUpdate.setRefundDesc(cutStr500(ExceptionUtils.getExceptionInfo(e)));
                    refundOverOrderManager.update(refundOverOrder);
                }
            }
        });

        return ReturnT.SUCCESS;
    }

    private String cutStr500(String s) {
        if(StringUtils.isNotBlank(s) && s.length() > 500) {
            return s.substring(0, 500);
        }
        return s;
    }

}
