package cn.freemud.management.service.handle;

import cn.freemud.base.util.DateUtil;
import cn.freemud.management.enums.coupon.CouponThirdChannelEnum;
import cn.freemud.management.enums.coupon.EcologyChannelTypeEnum;
import cn.freemud.management.enums.SettlementTypeEnum;
import cn.freemud.management.enums.coupon.ThirdCouponReportStatusEnum;
import cn.freemud.management.enums.coupon.ThirdCouponReportTypeEnum;
import cn.freemud.management.intercept.CouponServiceException;
import cn.freemud.management.intercept.DeliveryServiceException;
import cn.freemud.management.thirdparty.CouponBackstageClient;
import cn.freemud.management.thirdparty.request.coupon.RedeemReportQueryRequest;
import cn.freemud.management.thirdparty.response.coupon.RedeemReportQueryResponse;
import cn.freemud.management.thirdparty.response.coupon.SaasPageResponse;
import cn.freemud.management.thirdparty.response.coupon.SaasResponse;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.CashTypeEnum;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderInfoReqs;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderPayItemResp;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderSettlementResp;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * &copy; All rights Reserved
 * 三方券订单
 * @author wénkǎi.zhāng 2024-02-29
 * @since 1.0
 */
@Component
public class ThirdCouponOrderHandle {
    @Autowired
    private CouponBackstageClient couponBackstageClient;
    /**
     * 判断订单中是否使用了三方券
     * <pre>
     *     1. 小程序订单，使用了三方券抵扣
     *     2. 订单宝订单，使用了三方券支付
     * </pre>
     * @param orderInfo
     * @return 是/否
     */
    public static boolean isThirdCouponOrder(OrderInfoReqs orderInfo) {
        return isThirdCouponOrder(orderInfo.getOrderSettlementDetailList(), orderInfo.getOrderPayItemCreateReqList());
    }

    /**
     * 判断订单中是否使用了三方券
     * <pre>
     *     1. 小程序订单，使用了三方券抵扣
     *     2. 订单宝订单，使用了三方券支付
     * </pre>
     * @param orderBean
     * @return 是/否
     */
    public static boolean isThirdCouponOrder(OrderBeanV1 orderBean) {
        return isThirdCouponOrder(orderBean.getOrderSettlementDetailList(), orderBean.getOrderPayItem());
    }

    /**
     * 判断订单中是否使用了三方券
     * <pre>
     *     1. 小程序订单，使用了三方券抵扣
     *     2. 订单宝订单，使用了三方券支付
     * </pre>
     * @param orderSettlementDetailList
     * @param orderPayItemCreateReqList
     * @return 是/否
     */
    public static boolean isThirdCouponOrder(List<OrderSettlementResp> orderSettlementDetailList, List<OrderPayItemResp> orderPayItemCreateReqList) {
        // 判断是否使用了三方券抵扣
        if (CollectionUtils.isNotEmpty(orderSettlementDetailList)) {
            boolean isThirdCoupon = orderSettlementDetailList.stream()
                    .anyMatch(o ->
                            o.getSettlementType().equals(SettlementTypeEnum.MT_TG_GOODS_COUPON.getSettlementType())
                                    || o.getSettlementType().equals(SettlementTypeEnum.TIKTOK_TG_GOODS_COUPON.getSettlementType())
                    );
            if (isThirdCoupon) {
                return true;
            }
        }

        // 判断是否使用了三方券支付
        if (CollectionUtils.isNotEmpty(orderPayItemCreateReqList)) {
            return orderPayItemCreateReqList.stream().anyMatch(o -> o.getPayChannelType().toString().equals(CashTypeEnum.THIRD_COUPON.getCode()));
        }

        return false;
    }

    /**
     * 判断是否超过了券冲正时间
     * <pre></pre>
     * @param redeemDate
     * @param channelTypeEnum
     * @return
     */
    public static boolean isCancelTimeout(Date redeemDate, @Nullable EcologyChannelTypeEnum channelTypeEnum) {
        if (EcologyChannelTypeEnum.MEITUAN.equals(channelTypeEnum)) {
            // 美团券不能超过 60天
            if (DateUtil.addDays(redeemDate, 60).compareTo(new Date()) < 0) {
                return true;
            }
        } else if (EcologyChannelTypeEnum.TIKTOK.equals(channelTypeEnum)) {
            // 抖音券不能超过 1 小时（3600秒）
            if (redeemDate.getTime() + 3600_000 < System.currentTimeMillis()) {
                return true;
            }
        }

        return false;
    }

    /**
     * 通过非码订单号查询三方券信息
     * <pre></pre>
     * @param partnerId
     * @param orderCode
     * @return
     */
    @Nullable
    public ThirdCouponDto getCoupon(String partnerId, String orderCode) {
        RedeemReportQueryRequest request = new RedeemReportQueryRequest();
        request.setPartnerId(partnerId);
        request.setOrderCode(orderCode);
        SaasResponse<SaasPageResponse<RedeemReportQueryResponse>> saasResponse = couponBackstageClient.queryCodesInfo(request);
        ApiLog.infoMessage("查询券码服务:req={},resp={}", JSONObject.toJSONString(request), JSONObject.toJSONString(saasResponse));
        if (!saasResponse.getStatusCode().equals(100) || saasResponse.getResult() == null || CollectionUtils.isEmpty(saasResponse.getResult().getList())) {
            ErrorLog.errorDev("查询券码服务失败");
            return null;
        }
        Optional<RedeemReportQueryResponse> first = saasResponse.getResult().getList().stream()
                .filter(resp -> ThirdCouponReportTypeEnum.REDEEM.getType().equals(resp.getRedeemType()) && ThirdCouponReportStatusEnum.SUCCESS.getStatus().equals(resp.getRedeemStatus()))
                .findFirst();
        if (!first.isPresent()) {
            ErrorLog.errorDev("查询券码服务失败，无核销记录");
            return null;
        }
        RedeemReportQueryResponse redeemReport = first.get();
        List<String> couponCodes = Arrays.asList(redeemReport.getCouponCode().split(","));

        boolean canceled = saasResponse.getResult().getList().stream()
                .anyMatch(resp -> ThirdCouponReportTypeEnum.REVERSE.getType().equals(resp.getRedeemType()) && ThirdCouponReportStatusEnum.SUCCESS.getStatus().equals(resp.getRedeemStatus()));
        ThirdCouponDto thirdCouponDto = new ThirdCouponDto();
        thirdCouponDto.setCouponCodes(couponCodes);
        thirdCouponDto.setCanceled(canceled);
        thirdCouponDto.setPartnerId(redeemReport.getPartnerId());
        thirdCouponDto.setStoreId(redeemReport.getStoreId());
        thirdCouponDto.setMemberId(redeemReport.getMemberId());
        thirdCouponDto.setChannel(redeemReport.getChannel());
        if (CouponThirdChannelEnum.MEI_TUAN.getChannel().equals(redeemReport.getChannel())) {
            thirdCouponDto.setEcologyChannelType(EcologyChannelTypeEnum.MEITUAN);
        } else if (CouponThirdChannelEnum.DOU_YIN.getChannel().equals(redeemReport.getChannel())) {
            // 未知渠道的为早期对接抖音时的数据，默认为抖音渠道
            thirdCouponDto.setEcologyChannelType(EcologyChannelTypeEnum.TIKTOK);
        }

        return thirdCouponDto;

    }

    @Data
    public static class ThirdCouponDto {
        /**
         * 券渠道
         */
        private Short channel;
        /**
         * 券渠道
         */
        @Nullable
        private EcologyChannelTypeEnum ecologyChannelType;
        /**
         * 券号列表
         */
        private List<String> couponCodes;
        /**
         * 是否已冲正订单
         */
        private boolean canceled;

        /**
         * 商户号
         */
        private String partnerId;

        /**
         * 核销门店 id
         */
        private String storeId;

        /**
         * 会员 id
         */
        private String memberId;
    }
}
