package cn.freemud.management.service.handle;

import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.log.LogTreadLocal;
import cn.freemud.management.entities.dto.request.order.OrderManagerRequest;
import cn.freemud.management.entities.dto.response.order.OrderManagerResponse;
import cn.freemud.management.entities.dto.response.pay.RefundConfig;
import cn.freemud.management.enums.OrderRefundEnum;
import cn.freemud.management.enums.OrderSource;
import cn.freemud.management.enums.OrderStatus;
import cn.freemud.management.enums.ResponseResult;
import cn.freemud.management.util.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartnerWxappConfig;
import com.freemud.api.assortment.datamanager.manager.cache.CacheOpenPlatformPartnerWxappConfigManager;
import com.freemud.application.sdk.api.ordercenter.enums.AfterSalesType;
import com.freemud.application.sdk.api.ordercenter.enums.OperateClient;
import com.freemud.sdk.api.assortment.order.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant;
import com.freemud.sdk.api.assortment.message.enums.OrderType;
import com.freemud.sdk.api.assortment.order.adapter.OrderSdkAdapter;
import com.freemud.sdk.api.assortment.order.domain.ResponseCodeConstant;
import com.freemud.sdk.api.assortment.order.enums.OldOrderAccountType;
import com.freemud.sdk.api.assortment.order.enums.OldOrderType;
import com.freemud.sdk.api.assortment.order.enums.RefundStatus;
import com.freemud.sdk.api.assortment.order.request.order.CancelOrderRequest;
import com.freemud.sdk.api.assortment.order.response.order.BaseOrderResponse;
import com.freemud.sdk.api.assortment.order.response.order.QueryOrdersResponse;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0
 * @Title: OrderVerifyService
 * @Package cn.freemud.management.service.impl
 * @Description:
 * @author: shuhu.hou
 * @date: 2020/3/26 16:04
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
@Component
public class OrderVerifyHandle {

    /**
     * 允许退款
     */
    private static final String ALLOW_REFUND = "1";
    /**
     * svc储值卡支付，可用于判断订单是否用储值卡支付
     */
    private static final String PAY_CODE_10102 = "10102";

    @Autowired
    private CacheOpenPlatformPartnerWxappConfigManager cacheOpenPlatformPartnerWxappConfigManager;

    @Autowired
    private OrderSdkAdapter orderSdkAdapter;
    @Autowired
    private OrderCenterSdkService orderCenterSdkService;

    /**
     * 接单校验
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderConfirmTakeVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (orderBean == null) {
            return ResponseUtil.error(ResponseResult.ORDER_NOT_EXIST);
        }
        if (!OrderStatus.TAKE_ORDER.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_CANNOT_CONFIRM, getOrderManagerResponse(orderBean));
        }
        return ResponseUtil.success();
    }

    /**
     * 订单配送校验
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderDeliveryVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (orderBean == null) {
            return ResponseUtil.error(ResponseResult.ORDER_NOT_EXIST);
        }
        //已完成的订单不能配送
        if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_IS_COMPLETE_CAN_NOT_DELIVERY, getOrderManagerResponse(orderBean));
        }
        //订单已经发送过配送
        if (OrderStatus.DISTRIBUTION.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.DELIVERY_SEND_REPETITION, getOrderManagerResponse(orderBean));
        }
        //判断订单状态是否为已经申请退款订单
        if (orderBean.getHasRefund() != null
                && orderBean.getHasRefund()
                && (orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() == 1
                || orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() == 4)) {
            return ResponseUtil.error(ResponseResult.DELIVERY_SEND_APPLY_REFUND, getOrderManagerResponse(orderBean));
        }
        //外卖订单不是接单不能送出
        if (!OrderStatus.RECEIPT.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.DELIVERY_SEND_STATUS_NOTAKE, orderBean);
        }
        return ResponseUtil.success();
    }


    /**
     * 订单制作完成校验
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderDoneVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (orderBean == null) {
            return ResponseUtil.error(ResponseResult.ORDER_NOT_EXIST);
        }
        //已制作完成的订单不能重复操作
        if (OrderStatus.COMPLETE_MAKE.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.DONE_FAIL_REPETITION, getOrderManagerResponse(orderBean));
        }
        //订单非接单状态，不能制作完成
        if (!OrderStatus.RECEIPT.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.DONE_FAIL_NOT_ACCEPT, getOrderManagerResponse(orderBean));
        }
        //判断订单状态是否为已经申请退款订单
        if (orderBean.getHasRefund() != null
                && orderBean.getHasRefund()
                && (orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() == 1
                || orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() == 4)) {
            return ResponseUtil.error(ResponseResult.DONE_FAIL_APPLY_REFUND, getOrderManagerResponse(orderBean));
        }
        return ResponseUtil.success();
    }

    /**
     * 订单完成校验
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderAffirmVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (orderBean == null) {
            return ResponseUtil.error(ResponseResult.ORDER_NOT_EXIST);
        }
        //判断订单是否已送达
        if (OrderStatus.COMPLETE.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.DELIVERY_SEND_REPETITION, getOrderManagerResponse(orderBean));
        }
        //已取消的订单不能操作
        if (OrderStatus.CANCEL.getCode().equals(orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED, getOrderManagerResponse(orderBean));
        }
        //判断订单状态是否为已经申请退款订单
        if (orderBean.getHasRefund() != null
                && orderBean.getHasRefund()
                && (orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() == 1
                || orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() == 4)) {
            return ResponseUtil.error(ResponseResult.AFFIRM_FAIL_APPLY_REFUND, getOrderManagerResponse(orderBean));
        }
        //校验订单是否为配送状态
        if (isWaimai(orderBean) && ObjectUtils.notEqual(OrderStatus.DISTRIBUTION.getCode(), orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_DELIVERY_FAILED, getOrderManagerResponse(orderBean));
        }
        return ResponseUtil.success();
    }

    /**
     * 拒单
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderRejectVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (orderBean == null) {
            return ResponseUtil.error(ResponseResult.ORDER_NOT_EXIST);
        }
        Integer status = orderBean.getStatus();
        //判断订单是否已经被拒单
        if (OrderStatus.REFUSE.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_REPETITION, getOrderManagerResponse(orderBean));
        }
        //判断订单是否已经取消
        if (OrderStatus.CANCEL.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED, getOrderManagerResponse(orderBean));
        }
        //判断订单是否在配送中
        if (OrderStatus.DISTRIBUTION.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_ORDER_IS_DELIVERY, getOrderManagerResponse(orderBean));
        }
        //判断订单是否已送达
        if (OrderStatus.COMPLETE.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_ORDER_IS_COMPLETE, getOrderManagerResponse(orderBean));
        }
        if (!OrderStatus.TAKE_ORDER.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_ORDER_IS_NOT_NEW, getOrderManagerResponse(orderBean));
        }
        return ResponseUtil.success();
    }

    /**
     * 拒单
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse mcCafeOrderRejectVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (orderBean == null) {
            return ResponseUtil.error(ResponseResult.ORDER_NOT_EXIST);
        }
        Integer status = orderBean.getStatus();
        //判断订单是否已经被拒单
        if (OrderStatus.REFUSE.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_REPETITION, getOrderManagerResponse(orderBean));
        }
        //判断订单是否已经取消
        if (OrderStatus.CANCEL.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED, getOrderManagerResponse(orderBean));
        }
        //判断订单是否在配送中
        if (OrderStatus.DISTRIBUTION.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_ORDER_IS_DELIVERY, getOrderManagerResponse(orderBean));
        }
        //判断订单是否已送达
        if (OrderStatus.COMPLETE.getCode().equals(status)) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_ORDER_IS_COMPLETE, getOrderManagerResponse(orderBean));
        }
        if (!OrderStatus.TAKE_ORDER.getCode().equals(status) && !OldOrderType.TAKE_OUT.getCode().equals(orderBean.getOrderType())) {
            return ResponseUtil.error(ResponseResult.REJECT_FAIL_ORDER_IS_NOT_NEW, getOrderManagerResponse(orderBean));
        }
        return ResponseUtil.success();
    }

    /**
     * 同意退款
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderAgreeRefund(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        //已取消的订单不能操作
        if (ObjectUtils.equals(OrderStatus.CANCEL.getCode(), orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED);
        }
        //判断订单是否有申请退款
        if (orderBean.getHasRefund() == null
                || !orderBean.getHasRefund()
                || orderBean.getRefundList().get(orderBean.getRefundList().size() - 1).getStatus() != 1) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_NOT_APPLY);
        }
        //订单是否支持退款
        boolean isCanRefund = false;
        //订单
        boolean isRefundDeliveryFee=false;
        //saas渠道订单，已完成的订单不能操作, 商户配置已完成订单可退款可退款
        if (ObjectUtils.equals(orderBean.getSource(), OrderSource.SAAS.getSource())) {
            isCanRefund = getRefundConfig(orderBean);
            if (!isCanRefund) {
                return ResponseUtil.error(ResponseResult.ORDER_HAD_AFFIRM_CAN_NOT_REFUND);
            }
        }
        if (isCanRefund) {
            orderBean.setAmount(getRefundAmount(orderBean,isRefundDeliveryFee).longValue());
        }
        return ResponseUtil.success();
    }

    /**
     * 麦咖啡同意退款
     *
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderAgreeRefundMCCafe(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        //已取消的订单不能操作
        if (ObjectUtils.equals(OrderStatus.CANCEL.getCode(), orderBean.getStatus())) {
            return ResponseUtil.error(ResponseResult.ORDER_HAS_CANCELED);
        }
        for (QueryOrdersResponse.DataBean.OrderBean.RefundBean refundBean : orderBean.getRefundList()) {
            if(RefundStatus.APPLY_REFUND.getCode().equals(refundBean.getStatus())) {
                return ResponseUtil.success();
            }
            if(RefundStatus.COMPLETE_REFUND.getCode().equals(refundBean.getStatus())) {
                return ResponseUtil.error(ResponseResult.AGREE_REFUND_ORDER_FAIL.getCode(), "订单已经退款完成，不能重复申请");
            }
        }
        return ResponseUtil.success();
    }

    /**
     * 拒绝退款
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse orderRejectRefund(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        //判断当前订单是否发起退款
        if (orderBean.getHasRefund() == null || !orderBean.getHasRefund()) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_NOT_APPLY);
        }
        //判断该当前订单是否已经退款
        List<QueryOrdersResponse.DataBean.OrderBean.RefundBean> list = orderBean.getRefundList();
        if (ObjectUtils.equals(list.get(list.size() - 1).getStatus(), 5)) {
            return ResponseUtil.error(ResponseResult.ORDER_REJECT_REFUND_REPETITION);
        }
        //订单不是申请退款中，不能操作
        if (ObjectUtils.notEqual(list.get(list.size() - 1).getStatus(), 1)) {
            return ResponseUtil.error(ResponseResult.ORDER_REJECT_REFUND_STATUS_NOT);
        }
        //新订单，已完成，取消订单不能操作
        if (OrderSource.SAAS.getSource().equals(orderBean.getSource())
                && (OrderStatus.TAKE_ORDER.getCode().equals(orderBean.getStatus())
                || OrderStatus.CANCEL.getCode().equals(orderBean.getStatus()))) {
            return ResponseUtil.error(ResponseResult.ORDER_REJECT_REFUND_STATUS_END);
        }
        return ResponseUtil.success();
    }

    /**
     * 拒绝退款
     * @param orderBean
     * @param request
     * @return
     */
    public BaseResponse mcCafeOrderRejectRefund(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        //判断当前订单是否发起退款
        if (orderBean.getHasRefund() == null || !orderBean.getHasRefund()) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_NOT_APPLY);
        }

        if(CollectionUtils.isEmpty(orderBean.getRefundList())) {
            return ResponseUtil.error(ResponseResult.ORDER_REFUND_NOT_APPLY);
        }

        for (QueryOrdersResponse.DataBean.OrderBean.RefundBean refundBean : orderBean.getRefundList()) {
            if (ObjectUtils.equals(refundBean.getStatus(), RefundStatus.COMPLETE_REFUND.getCode())) {
                return ResponseUtil.error(ResponseResult.ORDER_REJECT_REFUND_REPETITION);
            }

            if (OrderStatus.CANCEL.getCode().equals(orderBean.getStatus())) {
                return ResponseUtil.error(ResponseResult.ORDER_REJECT_REFUND_STATUS_END);
            }

            if (ObjectUtils.equals(refundBean.getStatus(), RefundStatus.APPLY_REFUND.getCode())) {
                break;
            }
        }

        return ResponseUtil.success();
    }

    /**
     * 通用校验
     *
     * @param orderBean
     * @param request
     * @return
     */
    private BaseResponse commonVerify(QueryOrdersResponse.DataBean.OrderBean orderBean, OrderManagerRequest request) {
        if (ObjectUtils.notEqual(orderBean.getCompanyId(), request.getPartnerId())) {
            return ResponseUtil.error(ResponseResult.ORDER_PARTNER_ID_NOT_MATCTH, getOrderManagerResponse(orderBean));
        }
        //开放平台不传入门店
        if (ObjectUtils.notEqual(request.getOperator(), OperateClient.OPEN_PLATFORM.getOpName()) && ObjectUtils.notEqual(orderBean.getShopId(), request.getStoreId())) {
            return ResponseUtil.error(ResponseResult.ORDER_STORE_ID_NOT_MATCTH, getOrderManagerResponse(orderBean));
        }
        return ResponseUtil.success();
    }

    /**
     * 是否是外卖
     *
     * @param orderBean
     * @return
     */
    private boolean isWaimai(QueryOrdersResponse.DataBean.OrderBean orderBean) {
        String source = orderBean.getSource();
        if (OrderSource.BDWM.getSource().equals(source) || OrderSource.JDWM.getSource().equals(source)
                || OrderSource.MTWM.getSource().equals(source) || OrderSource.ELEME.getSource().equals(source)) {
            return true;
        }
        return false;
    }

    private OrderManagerResponse getOrderManagerResponse(QueryOrdersResponse.DataBean.OrderBean orderBean) {
        Integer refundStatus = CollectionUtils.isEmpty(orderBean.getRefundList()) ? null : orderBean.getRefundList().get(0).getStatus();
        return new OrderManagerResponse(orderBean.getGmtExpect(), orderBean.getStatus(), refundStatus);
    }

    /**
     * 已完成订单退款配置查询
     *
     * @param data
     * @return true=可同意退款
     */
    private boolean getRefundConfig(QueryOrdersResponse.DataBean.OrderBean data) {
        boolean isFinishRefund = false;
        com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto extInfo = null;
        JSONObject jsonObject1 = JSONObject.parseObject(data.getExtInfo());
        extInfo = jsonObject1.toJavaObject(com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto.class);
        List<AssortmentOpenPlatformPartnerWxappConfig> partnerWxappConfigs = cacheOpenPlatformPartnerWxappConfigManager.cacheSelectDefaultPage(extInfo.getAppid(), "2");
        Map<String, AssortmentOpenPlatformPartnerWxappConfig> configMap = partnerWxappConfigs.stream().collect(Collectors.toMap(AssortmentOpenPlatformPartnerWxappConfig::getAppKey, Function.identity()));
        AssortmentOpenPlatformPartnerWxappConfig orderRefund;

        //订单状态
        switch (data.getStatus()) {
            // 未接单
            case 1:
                //区分外卖单和到店订单，判断是否可以退款
                if(OrderType.TAKE_OUT.getCode().equals(data.getOrderType())) {
                    orderRefund = configMap.get(OrderRefundEnum.DELIVERY_TAKE_ORDER_REFUND.getKeyValue());
                }else {
                    orderRefund = configMap.get(OrderRefundEnum.TAKEORDER_REFUND.getKeyValue());
                }
                if (orderRefund == null || (orderRefund != null && ALLOW_REFUND.equals(orderRefund.getAppValue()))) {
                    isFinishRefund = true;
                }
                break;
            //已接单
            case 3:
                if(OrderType.TAKE_OUT.getCode().equals(data.getOrderType())) {
                    orderRefund = configMap.get(OrderRefundEnum.DELIVERY_RECEIPT_ORDER_REFUND.getKeyValue());
                }else {
                    orderRefund = configMap.get(OrderRefundEnum.RECEIPTORDER_REFUND.getKeyValue());
                }
                if (orderRefund == null || (orderRefund != null && ALLOW_REFUND.equals(orderRefund.getAppValue()))) {
                    isFinishRefund = true;
                }
                break;
            //制作完成
            case 31:
                if(OrderType.TAKE_OUT.getCode().equals(data.getOrderType())) {
                    orderRefund = configMap.get(OrderRefundEnum.DELIVERY_COMPLETE_MAKE_ORDER_REFUND.getKeyValue());
                }else {
                    orderRefund = configMap.get(OrderRefundEnum.COMPLETEMAKEORDER_REFUND.getKeyValue());
                }
                if (orderRefund != null && ALLOW_REFUND.equals(orderRefund.getAppValue())) {
                    isFinishRefund = true;
                }
                break;
            // 订单完成
            case 5:
                if(OrderType.TAKE_OUT.getCode().equals(data.getOrderType())) {
                    orderRefund = configMap.get(OrderRefundEnum.DELIVERY_ORDER_REFUND.getKeyValue());
                }else {
                    orderRefund = configMap.get(OrderRefundEnum.ORDER_REFUND.getKeyValue());
                }
                if (orderRefund != null && ALLOW_REFUND.equals(orderRefund.getAppValue())) {
                    isFinishRefund = true;
                }
                break;
            default:
                break;

        }
        return isFinishRefund;
    }

    /**
     * 获取已完成订单退款金额
     */
    private BigDecimal getRefundAmount(QueryOrdersResponse.DataBean.OrderBean data,boolean isRefundDeliveryFee) {
        //是否配置已完成订单可退款
        BigDecimal refundAmount = new BigDecimal(data.getAmount());
        if (isRefundDeliveryFee || isPayBySVC(data)){
            return refundAmount;
        }
        List<QueryOrdersResponse.DataBean.OrderBean.AccountBean> accountList = data.getAccountList();
        if (CollectionUtils.isNotEmpty(accountList)) {
            for (QueryOrdersResponse.DataBean.OrderBean.AccountBean orderCostResp : accountList) {
                if (orderCostResp.getType() == OldOrderAccountType.DELIVERY_AMOUNT.getCode()) {
                    refundAmount = new BigDecimal(data.getAmount().intValue() - orderCostResp.getPrice());
                }
            }
        }
        return refundAmount;
    }
    /**
     * 订单是否使用储值卡支付（储值卡支付的订单，不支持部分退款）
     *
     * @param order
     * @return true-是，false-不是
     */
    private boolean isPayBySVC(QueryOrdersResponse.DataBean.OrderBean order) {
        return PAY_CODE_10102.equalsIgnoreCase(order.getPayChannel());
    }
}
