package cn.freemud.service.business.impl;

import cn.freemud.amqp.MQService;
import cn.freemud.base.util.DateUtil;
import cn.freemud.entities.dto.GetMemberExtendInfoRequestDto;
import cn.freemud.entities.dto.GetMemberExtendInfoResponseDto;
import cn.freemud.entities.dto.GetUserScoreUserDetailDto;
import cn.freemud.entities.dto.user.UserScoreRequest;
import cn.freemud.service.business.OrderBusinessService;
import cn.freemud.service.impl.OrderQueueService;
import cn.freemud.service.thirdparty.CustomerApplicationClient;
import cn.freemud.service.thirdparty.CustomerClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.base.BaseResponse;
import com.freemud.application.sdk.api.couponcenter.offline.request.CouponRequest;
import com.freemud.application.sdk.api.couponcenter.offline.response.CouponLockResponse;
import com.freemud.application.sdk.api.couponcenter.offline.service.OfflineCouponSdkService;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.AfterSalesType;
import com.freemud.application.sdk.api.ordercenter.enums.OrderSettlementType;
import com.freemud.application.sdk.api.ordercenter.request.OrderCancelReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.request.PaySuccessReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderSettlementCreateReq;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderTaskReq;
import com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp;
import com.freemud.application.sdk.api.ordercenter.response.PaySuccessResp;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderInfoReqs;
import com.freemud.application.sdk.api.ordercenter.service.OrderSdkService;
import com.freemud.application.sdk.api.promotioncenter.request.promotion.ActivityUpdateStockRequest;
import com.freemud.application.sdk.api.promotioncenter.service.PromotionSdkService;
import com.freemud.application.sdk.api.stockapi.request.UpdateStocksRequest;
import com.freemud.application.sdk.api.stockapi.service.StockSdkService;
import com.freemud.application.sdk.api.storecenter.request.StoreInfoRequest;
import com.freemud.application.sdk.api.storecenter.request.vo.GetOrgTreeListRequest;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.application.sdk.api.storecenter.response.vo.GetOrgTreeListResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.order.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.constant.CommonConstant;
import com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant;
import com.freemud.sdk.api.assortment.order.enums.*;
import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.response.order.BaseOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.CreateOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.PayAccessResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.freemud.application.sdk.api.membercenter.constant.InterfaceAddressConstant.MEMBER_EXTEND_INFO;
import static com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant.RESPONSE_SUCCESS;
import static com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant.RESPONSE_SUCCESS_STR;

/**
 * @ClassName: OrderBusinessServiceImpl
 * @Description:
 * @Author: freemud
 * @Date: 2021/6/9 下午4:12
 */
@Service
public class OrderBusinessServiceImpl implements OrderBusinessService {

    @Autowired
    private OrderSdkAdapter orderSdkAdapter;
    @Autowired
    private StoreCenterService storeCenterService;
    @Autowired
    private OrderSdkService orderSdkService;
    @Autowired
    private CustomerClient customerClient;
    @Autowired
    private StockSdkService stockSdkService;
    @Autowired
    private PromotionSdkService promotionSdkService;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
//    private MemberScoreService memberScoreService;
    @Autowired
    private OfflineCouponSdkService offlineCouponSdkService;
    @Autowired
    private MQService mqService;
    @Autowired
    private OrderQueueService orderQueueService;

    @Value("${version.upgrade.weekDay:}")
    private List<Integer> weekDay;
    /**
     *  规避 发版时间配置的双虎
     */
    @Value("${avoid.version.upgrade.config:}")
    private String avoidVersionUpgradeConfig;




    @Override
    public PayAccessResponse payAccess(ConfirmOrderRequest confirmOrderRequest) {
        PaySuccessReq request = new PaySuccessReq();
        request.setPayRequestNo(confirmOrderRequest.getPayVoucher());
        request.setCompleteOrderCode(confirmOrderRequest.getCompleteOrderCode());
        request.setOrderCode(confirmOrderRequest.getOrderId());
        request.setMealCodeRule(confirmOrderRequest.getMealCodeRule());
        request.setPickUpGoodsNo(confirmOrderRequest.getPickUpGoodsNo());
        // 引入门店基础服务 查询自动制作完成配置时间，预约单单独超时任务设置
        request.setTimeout(getPaySuccessTimeout(confirmOrderRequest, request));

        if (!org.springframework.util.CollectionUtils.isEmpty(confirmOrderRequest.getOrderSettlements())) {
            List<OrderSettlementCreateReq> orderSettlementCreateReqs = new ArrayList<>();
            int size = confirmOrderRequest.getOrderSettlements().size();
            OrderSettlementCreateReq orderSettlementCreateReq = new OrderSettlementCreateReq();
            for (int i = 0; i < size; i++) {
                ConfirmOrderRequest.OrderSettlement orderSettlement = confirmOrderRequest.getOrderSettlements().get(i);
                orderSettlementCreateReq.setPlatformDiscountAmount(orderSettlement.getPlatformDiscountAmount());
                orderSettlementCreateReq.setShopDiscountAmount(orderSettlement.getShopDiscountAmount());
                orderSettlementCreateReq.setSettlementAmount(orderSettlement.getSettlementAmount());
                orderSettlementCreateReq.setNote(orderSettlement.getNote());
                orderSettlementCreateReq.setSettlementType(this
                        .convertAssortmentSettlementTypeToNewOrderSettlementType(orderSettlement.getSettlementType()));
                orderSettlementCreateReqs.add(orderSettlementCreateReq);
            }
            request.setOrderSettlementDetailList(orderSettlementCreateReqs);
        }
        request.setActualPayAmount(confirmOrderRequest.getActualPayAmount());
        request.setOperator(confirmOrderRequest.getOperator());
        if (StringUtils.isNotBlank(confirmOrderRequest.getPayChannel())) {
            request.setPayChannel(confirmOrderRequest.getPayChannel());
            request.setPayChannelName(confirmOrderRequest.getPayChannelName());
        }
//        QueryOrderByIdResponse orderByIdResponse = new QueryOrderByIdResponse();
//        BaseResponse<GetMemberExtendInfoResponseDto> extendInfo = new BaseResponse();
        try {
//            QueryByCodeResponse codeResponse = orderSdkService.getOrderInfo(confirmOrderRequest.getProductOrderCode(),
//                    0, confirmOrderRequest.getTrackingNo());
//            orderByIdResponse = orderSdkAdapter.convent2QueryOrderByIdResponse(codeResponse);

            GetMemberExtendInfoRequestDto extendInfoRequest = new GetMemberExtendInfoRequestDto();
            extendInfoRequest.setMemberId(confirmOrderRequest.getUserId());
            extendInfoRequest.setPartnerId(confirmOrderRequest.getPartnerId());
            extendInfoRequest.setIsQueryGrade(1);
            extendInfoRequest.setIsQueryLabel(0);
            extendInfoRequest.setIsQueryPaid(1);
            BaseResponse<GetMemberExtendInfoResponseDto> extendInfo = customerClient.getMemberExtendInfo(extendInfoRequest);
            OrderExtInfoDto extInfoDTO = new OrderExtInfoDto();
            if (StringUtils.isNotBlank(confirmOrderRequest.getExtInfo())){
                extInfoDTO = JSONObject.parseObject(confirmOrderRequest.getExtInfo(),OrderExtInfoDto.class);
            }
            if (null == extendInfo.getData()) {
                extInfoDTO.setMemberLevel("");
                extInfoDTO.setPaidMember(false);
            } else {
                extInfoDTO.setMemberLevel(extendInfo.getData().getMemberGrade() != null ? extendInfo.getData().getMemberGrade().getRuleName(): "");
                extInfoDTO.setPaidMember(CollectionUtils.isNotEmpty(extendInfo.getData().getMemberPaids()));
            }
            extInfoDTO.setPayTransId(confirmOrderRequest.getPayTransId());
            extInfoDTO.setPayDate(confirmOrderRequest.getPayDate());
            extInfoDTO.setEndTransId(confirmOrderRequest.getEndTransId());
            request.setExtInfo(JSON.toJSONString(extInfoDTO));
            if (StringUtils.isNotEmpty(confirmOrderRequest.getSpellGroupCode())) {
                request.setSpellGroupCode(confirmOrderRequest.getSpellGroupCode());
            }
        } catch (Exception e) {
            ErrorLog.printErrorLog("getMemberExtendInfoError", MEMBER_EXTEND_INFO, confirmOrderRequest, e);
        }
        OrderBaseResp<PaySuccessResp> response = orderSdkService
                .paySuccess(request, confirmOrderRequest.getTrackingNo());
        return orderSdkAdapter.convent2PayAccessResponse(response);
    }

    @Override
    public Integer getPaySuccessTimeout(ConfirmOrderRequest confirmOrderRequest, PaySuccessReq request) {
        // 合阔pos 商户未接单退款超时时间
        if (confirmOrderRequest.getNotAutomaticTwistTime() != null) {
            return confirmOrderRequest.getNotAutomaticTwistTime();
        }

        Integer timeout = 0;
        StoreInfoRequest storeInfoRequest = new StoreInfoRequest();
        storeInfoRequest.setPartnerId(confirmOrderRequest.getPartnerId());
        storeInfoRequest.setStoreCode(confirmOrderRequest.getStoreId());
        StoreResponse storeResponse = storeCenterService.getStoreInfo(storeInfoRequest,
                confirmOrderRequest.getTrackingNo());
        if (storeResponse != null && storeResponse.getBizVO() != null) {
            StoreResponse.Configuration configuration = storeResponse.getBizVO().getStoreConfig();
            // 配置为空超时取消订单
            if (configuration == null
                    || org.apache.commons.lang.StringUtils.isBlank(configuration.getOverTimeCloseOrder())) {
                timeout = 30;
            }
            // 超时关单开启
            if (configuration != null && ObjectUtils.equals("1", configuration.getOverTimeCloseOrder())
                    && StringUtils.isNotBlank(configuration.getOverTimeCloseOrderTime())) {
                timeout = Integer.parseInt(configuration.getOverTimeCloseOrderTime());
            }
            // isAutoTakeOrder = 3为服务端超时接单
            if ("3".equals(storeResponse.getBizVO().getIsAutoTakeOrder())) {
                // 外卖订单
                if (confirmOrderRequest.getOrderType() == OldOrderType.TAKE_OUT.getCode()) {
                    timeout = PaySuccessTimeoutEnum.getMin(configuration.getTakeOutAutomaticOrderTime());
                } else {
                    timeout = PaySuccessTimeoutEnum.getMin(configuration.getPickUpAutomaticOrderTime());
                }
            }
        }
        return timeout;
    }

    @Override
    public CreateOrderResponse createOrderFlow(CreateOrderRequest config) {

        com.freemud.application.sdk.api.ordercenter.request.create.CreateOrderRequest request = orderSdkAdapter.convent2NEWCreateOrderRequest(config.getBaseCreateOrderRequest());
//        AssortOrderLogUtil.info("fisherman 请求基础服务,最终构建 04",config!=null?JSON.toJSONString(config):null);
        // fisherman 创建订单 extinfo 存储 信息,有数上报需要使用, 更新接口直接重新覆盖就行
        request.setExtInfo(this.getTempExtInfoMsg(config.getOpenId(),config.getBaseCreateOrderRequest().getAppId()));
        OrderBaseResp<OrderInfoReqs> order = orderSdkService.createOrder(request, config.getTrackingNo());
        CreateOrderResponse createOrderResponse = orderSdkAdapter.convent2NEWOrderInfoReqs(order);
        if (!RESPONSE_SUCCESS.equals(createOrderResponse.getErrcode())
                || createOrderResponse.getData() == null) {
            return getCreateOrderResponse(createOrderResponse.getErrcode().toString(), createOrderResponse.getErrmsg(), null);
        }
        //更新库存等信息
        BaseOrderResponse baseOrderResponse = updateStockAndScore(createOrderResponse.getData(), config.getBaseCreateOrderRequest().getProducts(), config.getBaseCreateOrderRequest().getActivityUpdateStockRequest(),
                config.getBaseCreateOrderRequest().getAccounts(), config.getBaseCreateOrderRequest().getMenuType(),config.getOpenId(),config.getBaseCreateOrderRequest().getTotalScore());
        if (!RESPONSE_SUCCESS.equals(baseOrderResponse.getErrcode())) {
            return getCreateOrderResponse(baseOrderResponse.getErrcode().toString(), baseOrderResponse.getErrmsg(), null);
        }
        return createOrderResponse;
    }

    private String getTempExtInfoMsg(String openId, String appId) {
        OrderExtInfoDto orderExtInfoDto = new OrderExtInfoDto();
        orderExtInfoDto.setAppid(appId);
        orderExtInfoDto.setOpenid(openId);
        return JSON.toJSONString(orderExtInfoDto);
    }

    private Integer convertAssortmentSettlementTypeToNewOrderSettlementType(OldOrderAccountType settlementType) {
        if (settlementType == OldOrderAccountType.WEIXIN) {
            return OrderSettlementType.WEIXIN.getIndex();
        }
        return -1;
    }


    public CreateOrderResponse getCreateOrderResponse(String code, String message, OrderBeanV1 data) {
        CreateOrderResponse baseOrderResponse = new CreateOrderResponse();
        baseOrderResponse.setErrcode(Integer.valueOf(code));
        baseOrderResponse.setErrmsg(message);
        baseOrderResponse.setData(data);
        return baseOrderResponse;
    }

    /**
     * 创建订单后扣减库存等操作
     * @return
     */
    private BaseOrderResponse updateStockAndScore(OrderBeanV1 orderBean, List<CreateOrderProductRequest> products, ActivityUpdateStockRequest updateStockRequest,
                                                  List<CreateOrderAccountRequest> accounts, String menuType, String openId,Long totalScore) {
        //TODO 转换获取库存信息,扣减库存
        UpdateStocksRequest updateStocksRequest = orderSdkAdapter.getUpdateProductStock(orderBean, products, StockChangeType.REDUCE,menuType);
        if (updateStocksRequest != null && CollectionUtils.isNotEmpty(updateStocksRequest.getProductStocks())) {
            BaseResponse baseResponse = stockSdkService.reducesStocks(updateStocksRequest, "");
            if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, baseResponse.getCode())) {
                //TODO 失败取消订单
                CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                        AfterSalesType.SYSTEM_CANCEL, "商品库存不足", "", null);
                orderCancel(cancelOrderRequest);
                return BaseOrderResponse.getErrorBaseOrderResponse(baseResponse.getCode(), "商品库存不足");
            }
        }
        //TODO 扣减活动库存
        ActivityUpdateStockRequest activityUpdateStockRequest = orderSdkAdapter.convert2ActivityUpdateStockRequest(orderBean, updateStockRequest);
        // update by miaohui 20201030 for 【ID1018638】【C端服务端】活动库存接口调整对接
        // 原逻辑只检测扣减库存不为空时调用，现改为扣减库存不为空或参加活动不为空时调用
        if (activityUpdateStockRequest != null && (CollectionUtils.isNotEmpty(activityUpdateStockRequest.getStock()) || CollectionUtils.isNotEmpty(activityUpdateStockRequest.getActivityList()))) {
            BaseResponse activityResponse = promotionSdkService.subtractStock(activityUpdateStockRequest, "");
            if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, activityResponse.getCode())) {
                //TODO 失败取消订单,异步冲正库存
                CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                        AfterSalesType.SYSTEM_CANCEL, "活动库存不足", "", null);
                orderCancel(cancelOrderRequest);
                //失败异步冲正库存，取消订单
                orderQueueService.backOrdersStatusChange(orderBean.getOid(),orderBean.getStatus());
                return BaseOrderResponse.getErrorBaseOrderResponse(activityResponse.getCode(), "活动库存不足");
            }
        }

        UserScoreRequest userScoreRequest = this.convent2UserScoreRequest(orderBean, accounts, true,totalScore);
        // 扣减积分，扣减失败冲正积分返回错误
        if (userScoreRequest != null) {
            GetUserScoreUserDetailDto userScoreResponse = customerApplicationClient.useScore(userScoreRequest);
            if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, userScoreResponse.getCode())) {
                //TODO 失败取消订单,异步冲正库存
                CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                        AfterSalesType.SYSTEM_CANCEL, "积分不足", "", null);
                orderCancel(cancelOrderRequest);
                //失败异步冲正库存，取消订单
                orderQueueService.backOrdersStatusChange(orderBean.getOid(),orderBean.getStatus());
                return BaseOrderResponse.getErrorBaseOrderResponse(userScoreResponse.getCode(), "积分不足");
            }
        }

        // 下单成锁定劵，冻结失败提示下单失败并冲正库存积分等,判断支付渠道，积分和svc卡直接核销，无需锁定10102 = svc卡支付 || 支付金额小于等于0
        //todo:统一流程 下单锁券再核销
        CouponRequest request = orderSdkAdapter.convert2PreCheckRequest(orderBean, accounts, openId);
        if (request != null) {
            request.setChannel_ids(getOrgCodes(orderBean.getCompanyId(),orderBean.getShopId()));
            BaseResponse<CouponLockResponse> couponLockResponseBaseResponse = offlineCouponSdkService.precheckAndLock(request, LogThreadLocal.getTrackingNo());
            if (!ObjectUtils.equals(RESPONSE_SUCCESS_STR, couponLockResponseBaseResponse.getCode())) {
                CancelOrderRequest cancelOrderRequest = orderSdkAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(), AfterSalesType.SYSTEM_CANCEL, "锁定券码失败", "", null);
                orderCancel(cancelOrderRequest);
                //失败异步冲正库存，取消订单
                orderQueueService.backOrdersStatusChange(orderBean.getOid(),orderBean.getStatus());
                return BaseOrderResponse.getErrorBaseOrderResponse(couponLockResponseBaseResponse.getCode(), couponLockResponseBaseResponse.getMessage());
            }
        }
        return BaseOrderResponse.getErrorBaseOrderResponse(RESPONSE_SUCCESS_STR, "");
    }



    @Override
    public BaseOrderResponse orderCancel(CancelOrderRequest cancelOrderRequest) {
        OrderCancelReq request = new OrderCancelReq();
        //商户号必传
        request.setPartnerId(cancelOrderRequest.getPartnerId());
        request.setOrderCode(cancelOrderRequest.getOrderId());
        request.setReqRemark(cancelOrderRequest.getReqRemark());
        //售后单类型 1:其他取消 2:用户取消 3:商户取消 4:未支付超时关单 5:商户接单超时取消 6:商家拒单
        // 7:配送用户拒收 8:用户售后退货/售后退款 9:系统取消 10:客服取消 11:用户统一取消，
        request.setAfterSalesType(cancelOrderRequest.getAfterSalesType().getIndex() == null ? 1 : cancelOrderRequest.getAfterSalesType().getIndex());
        request.setOrderClient(cancelOrderRequest.getOrderClient());
        request.setCancelReason(cancelOrderRequest.getReason());
        request.setAfterSalesReason(cancelOrderRequest.getReason());
        //若为4，默认做【创建】+【同意并退款完成】，售后单状态为【完成】
        request.setCreateEvent(cancelOrderRequest.getCreateEvent());
        request.setAfterSerialNo(cancelOrderRequest.getRefundSerialNo());
        request.setOperator(cancelOrderRequest.getOperator());

        // 【华莱士20210510活动】新增加退款方式字段
        if(Objects.nonNull(cancelOrderRequest.getExtInfoReq())){
            request.setExtInfo(JSON.toJSONString(cancelOrderRequest.getExtInfoReq()));
        }

        //为空发起售后单
        if(cancelOrderRequest.getCreateEvent() == null){
            // 查询门店服务配置，退单模式为2为自动退款，判断自动退款时间,设置为0则不传入timeout,
            StoreResponse.Configuration configuration = getStoreAutoConfiguration(cancelOrderRequest.getPartnerId(), cancelOrderRequest.getStoreId(), cancelOrderRequest.getTrackingNo());
            if (configuration != null && ObjectUtils.equals("2", configuration.getAutoChargebackOrderType())
                    && !ObjectUtils.equals("0", configuration.getAutoChargebackOrderTime())) {
                request.setTimeOut(AutoOrderConfigTime.getTime(configuration.getAutoChargebackOrderTime()));
            }
            OrderTaskReq orderTask = setAfterSalesOrderTimeOutTask(configuration,cancelOrderRequest.getPartnerId());
            request.setOrderTask(orderTask);
        }
        request.setRefundDeliveryAmount(cancelOrderRequest.isRefundDeliveryAmount());
        OrderBaseResp response = orderSdkService.cancelOrder(request, cancelOrderRequest.getTrackingNo());
        return orderSdkAdapter.convent2BaseOrderResponse(response);
    }



//    private void backOrdersNotifyActivity(OrderBeanV1 orderBean, String backOrdersChangeOrderStatusConsumerQueue, String backOrdersNotifyActivityExchange) {
//        if (null == orderBean || backOrdersChangeOrderStatusConsumerQueue == null || backOrdersNotifyActivityExchange == null) {
//            return;
//        }
//        String oid = orderBean.getOid();
//        Integer status = orderBean.getStatus();
//        if (StringUtils.isEmpty(oid)) {
//            return;
//        }
//        AssortOrderLogUtil.info("backOrdersStatusChange", oid, String.valueOf(status));
//        OrderStatusChangeRequestDto requestDto = new OrderStatusChangeRequestDto();
//        requestDto.setOid(oid);
//        requestDto.setOrderStatus(status);
//        try {
//            Header header = new Header(MQAction.INSERT.getAction(), "backOrdersStatusChange", oid, backOrdersChangeOrderStatusConsumerQueue);
//            MQMessage<OrderStatusChangeRequestDto> message = new MQMessage<>(header, requestDto);
//            mqService.convertAndSend(backOrdersNotifyActivityExchange, backOrdersChangeOrderStatusConsumerQueue, message);
//        } catch (Exception e) {
//            //TODO 邮件告警
//            ThirdPartyLog.infoConvertJson(System.currentTimeMillis(), System.currentTimeMillis(),
//                    "backOrdersStatusChangeNotify_error", backOrdersNotifyActivityExchange, backOrdersChangeOrderStatusConsumerQueue);
//        }
//    }

    List<String> getOrgCodes(String partnerId, String storeCode) {
        GetOrgTreeListRequest request = new GetOrgTreeListRequest();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeCode);
        BaseResponse<GetOrgTreeListResponse> orgList = storeCenterService.getOrgTreeList(request, LogThreadLocal.getTrackingNo());
        if (orgList != null && ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(orgList.getCode())) {
            List<GetOrgTreeListResponse.OrgList> orgResponseList = orgList.getData().getOrgList();
            if (CollectionUtils.isEmpty(orgResponseList)){
                return null;
            }
            return orgResponseList.stream().map(org -> org.getOrganizationId()).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 获取门店自动配置信息
     *
     * @param partnerId
     * @param storeCode
     * @param trackingNo
     * @return
     */
    private StoreResponse.Configuration getStoreAutoConfiguration(String partnerId, String storeCode, String trackingNo) {
        if (StringUtils.isEmpty(storeCode)) {
            return null;
        }
        StoreInfoRequest storeInfoRequest = new StoreInfoRequest();
        storeInfoRequest.setPartnerId(partnerId);
        storeInfoRequest.setStoreCode(storeCode);
        StoreResponse storeResponse = storeCenterService.getStoreInfo(storeInfoRequest, trackingNo);
        if (storeResponse == null || storeResponse.getBizVO() == null || storeResponse.getBizVO().getStoreConfig() == null) {
            return null;
        }

        return storeResponse.getBizVO().getStoreConfig();
    }


    /**
     * 设置申请退款时间
     * 如果时间的类型是2表示采用原来的48小时逻辑
     * 如果时间的类型是1表示在指定的时间之后进行退款
     * 为了防止同一时刻的退款量太大，需要将退款的订单分散到指定的时间后半小时内
     */
    public OrderTaskReq setAfterSalesOrderTimeOutTask(StoreResponse.Configuration configuration, String partnerId) {
        if(configuration == null ){
            return null;
        }
        OrderTaskReq orderTask;

        if((configuration.getTimeTypeOfRefund() != null && configuration.getTimeTypeOfRefund().compareTo(2) == 0 ) || configuration.getTimeTypeOfRefund() == null){// 48小时之后
            orderTask = new OrderTaskReq();
            orderTask.setTaskType(4);
            orderTask.setTimeout(1);
            //1000*60*60*24*2 毫秒（48小时）
            long timeout = 172800000;
            long timeMillis = System.currentTimeMillis();
            Date processingDate = new Date(timeMillis + timeout - 60000);
            Date taskTime = new Date(timeMillis + timeout);
            orderTask.setTaskTime(DateUtil.convert2String(taskTime, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
            //处理时间，当前时间加48小时减1分钟
            orderTask.setProcessingTime(DateUtil.convert2String(processingDate, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
        }else if(configuration.getTimeTypeOfRefund() != null && configuration.getTimeTypeOfRefund().compareTo(1) == 0 ){// 指定时间
            orderTask = new OrderTaskReq();
            orderTask.setTaskType(4);
            orderTask.setTimeout(1);
            // 获取门店配置的当天指定的退款时间
            String timeOfRefund = configuration.getTimeOfRefund();
            // 获取半小时的随机数
            Random r = new Random();
            int minute = r.ints(1,31).findFirst().getAsInt() * 60000;
            String today = DateUtil.getCurrentDate(DateUtil.FORMAT_YMD);

            Date configTime = DateUtil.convert2Date(today+" "+timeOfRefund, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
            // 判断当前时间是否已经超过门店设置的截至时间
            if(new Date().after(configTime)){
                today = DateUtil.convert2String(DateUtil.addDays(new Date(),1),DateUtil.FORMAT_YMD);
                configTime = DateUtil.convert2Date(today+" "+timeOfRefund, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
            }
            Date processingDate = new Date(configTime.getTime() + minute);
            String processingStr = DateUtil.convert2String(processingDate, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
            orderTask.setTaskTime(processingStr);
            orderTask.setProcessingTime(processingStr);
        } else {
            orderTask = null;
        }

        // fisherman [KA-20210702] 规避版本升级
        if (orderTask != null) {
            avoidVersionUpgrade(orderTask,partnerId);
        }
        return orderTask;
    }


    /**
     *  fisherman 规避版本升级
     *  周二周四晚 23:00开始发版, 服务器会存在宕机, 延迟定时器处理时间
     *  1.校验时间
     *  2.校验 apollo配置商户
     * @param orderTask
     */
    private void avoidVersionUpgrade(OrderTaskReq orderTask, String partnerId) {
        if (Objects.isNull(partnerId)) {
            return;
        }
        // 时间校验
        boolean checkResult = checkDate(orderTask);
        if (checkResult && StringUtils.isNotBlank(avoidVersionUpgradeConfig)) {
            // 读取 是否商户配置
            Map<String,Integer> map = JSON.parseObject(avoidVersionUpgradeConfig, Map.class);
            if (map.containsKey(partnerId)) {
                Integer addHours = map.get(partnerId);
                // 增加 时间
                String processingTime = orderTask.getProcessingTime();
                Date datet = DateUtil.convert2Date(processingTime, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
                Date date = DateUtil.addHours(datet, addHours);
                String resultTime = DateUtil.convert2String(date, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
                orderTask.setProcessingTime(resultTime);

                // 显示时间一起设置
                processingTime = orderTask.getProcessingTime();
                datet = DateUtil.convert2Date(processingTime, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
                date = DateUtil.addHours(datet, addHours);
                resultTime = DateUtil.convert2String(date, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
                orderTask.setTaskTime(resultTime);
            }

        }
    }


    private boolean checkDate(OrderTaskReq orderTask) {
        // 校验 是否 周二 周四
        String processingTime = orderTask.getProcessingTime();
        Calendar cal = Calendar.getInstance();
        Date datet = DateUtil.convert2Date(processingTime, DateUtil.FORMAT_YYYY_MM_DD_HHMMSS);
        if (datet == null) {
            return false;
        }
        cal.setTime(datet);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        // 增加一个发版开关
        if (CollectionUtils.isNotEmpty(weekDay) && weekDay.size()>0) {
            if (weekDay.contains(w)) {
                // 校验时间 是否是 23:00 之后
                int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
                if (hourOfDay >= 23){
                    // 表示 设置时间为23点之后
                    return true;
                }
            }
        }else {
            if (CommonConstant.weekDay.contains(w)) {
                // 校验时间 是否是 23:00 之后
                int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
                if (hourOfDay >= 23){
                    // 表示 设置时间为23点之后
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 积分扣减或冲正 (积分抵现或积分商品活动)
     *
     * @param orderBean 订单
     * @param accounts  订单优惠明细
     * @param isReduce  是否扣减：true扣减；false冲正
     * @return
     */
    public UserScoreRequest convent2UserScoreRequest(OrderBeanV1 orderBean, List<CreateOrderAccountRequest> accounts, boolean isReduce, Long totalScore) {
        UserScoreRequest userScoreRequest = null;
        Integer reduceAmount = 0;
        if (CollectionUtils.isNotEmpty(accounts)) {
            Optional<CreateOrderAccountRequest> accountRequest = accounts.stream().filter(account -> account.getAccountType().getCode().equals(QueryOrderAccountType.CUSTOMER_SCORE.getCode())).findFirst();
            if(accountRequest.isPresent() && accountRequest.get().getPrice() != 0){
                reduceAmount = accountRequest.get().getPrice().intValue();
            }
        }
        if(reduceAmount != 0 || (totalScore != null && totalScore != 0)){
            userScoreRequest = new UserScoreRequest();
            userScoreRequest.setMemberId(orderBean.getUserId());
            userScoreRequest.setPartnerId(orderBean.getCompanyId());
            userScoreRequest.setReduceAmount(reduceAmount * -1);
            userScoreRequest.setScoreOrderNo(orderBean.getOid());
            userScoreRequest.setChangeType(isReduce ? 2 : 1);
            userScoreRequest.setOperationType(isReduce ? 14 : 2);
            userScoreRequest.setStoreId(orderBean.getShopId());
            userScoreRequest.setProductScore(totalScore.intValue());
        }
        return userScoreRequest;
    }

}
