package cn.freemud.management.service.handle;

import cn.freemud.base.entity.BaseResponse;
import cn.freemud.management.entities.dto.request.order.OrderManagerRequest;
import cn.freemud.management.entities.dto.response.coupon.CouponBaseResponse;
import cn.freemud.management.enums.ResponseResult;
import cn.freemud.management.thirdparty.CouponOnlineClient;
import cn.freemud.management.thirdparty.request.coupon.BatchCouponDiscardReq;
import cn.freemud.management.thirdparty.request.coupon.CodeFreezeReq;
import cn.freemud.management.thirdparty.request.coupon.CouponUnFreezeReq;
import cn.freemud.management.util.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.BizTypeEnum;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderSettlementResp;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

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

/**
 * &copy; All rights Reserved
 *
 * @author wénkǎi.zhāng 2024-01-02
 * @since 1.0
 */
@Component
@RequiredArgsConstructor
public class OrderCouponHandle {
    @Value("${coupon.partner.id:1983}")
    private String couponPartnerId;

    private final CouponQueryHandle couponQueryHandle;
    private final CouponOnlineClient couponOnlineClient;

    public BaseResponse discardOrderCoupon(String partnerId, OrderBeanV1 orderBean) {
        if (BizTypeEnum.SALE_COUPON.getBizType().equals(orderBean.getBizType())) {
            List<String> couponCodes = Optional.ofNullable(orderBean.getOrderSettlementDetailList()).orElse(new ArrayList<>()).stream()
                    // 216 = 买券订单的券信息
                    .filter(dto -> Objects.equals(216, dto.getSettlementType()) && StringUtils.isNotBlank(dto.getExternalObjectId()))
                    .map(OrderSettlementResp::getExternalObjectId)
                    .collect(Collectors.toList());

            if (couponCodes.isEmpty()) {
                return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "订单中优惠券数据为空。");
            }
//            // 校验券状态是否已被使用
//            if (couponQueryHandle.isCouponUsed(partnerId, couponCodes)) {
//                return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "作废优惠券失败，部分券已被使用。");
//            }

            BatchCouponDiscardReq discardReq = new BatchCouponDiscardReq();
            discardReq.setCoupons(couponCodes.stream().map(code -> {
                return new BatchCouponDiscardReq.CouponInfo(){{
                    setCode(code);
                    setMemberId(orderBean.getUserId());
                }};
            }).collect(Collectors.toList()));
            discardReq.setPartnerId(partnerId);
            discardReq.setProviderId(couponPartnerId);
            discardReq.setCancelReason("券包订单退款");

            CouponBaseResponse<Object> discardResp = couponOnlineClient.batchDiscard(discardReq);
            if (!Objects.equals(discardResp.getStatusCode(), 100)) {
                return ResponseUtil.error(ResponseResult.SYSTEM_ERROR.getCode(), "作废优惠券失败");
            }
        }
        return ResponseUtil.success();
    }

    /**
     * 冻结券
     * <pre></pre>
     * @param partnerId
     * @param memberId
     * @param codes 注意所有券号尾号必须相同
     * @param reason
     * @return
     */
    public boolean freezeCodes(String partnerId, String memberId, Collection<String> codes, String reason) {
        CodeFreezeReq req = new CodeFreezeReq();
        req.setPartnerId(partnerId);
        req.setReason(reason);
        req.setCoupons(codes.stream().map(code -> {
            return new CodeFreezeReq.CouponInfo(){{
                setCode(code);
                setMemberId(memberId);
            }};
        }).collect(Collectors.toList()));

        CouponBaseResponse<Object> freeze = couponOnlineClient.freeze(req);
        return Objects.equals(freeze.getStatusCode(), 100);
    }

    /**
     * 解冻券
     * <pre></pre>
     * @param partnerId
     * @param orderBean
     */
    public void unfreezeOrderCoupon(String partnerId, OrderBeanV1 orderBean) {
        if (BizTypeEnum.SALE_COUPON.getBizType().equals(orderBean.getBizType())) {
            List<String> couponCodes = Optional.ofNullable(orderBean.getOrderSettlementDetailList()).orElse(new ArrayList<>()).stream()
                    // 216 = 买券订单的券信息
                    .filter(dto -> Objects.equals(216, dto.getSettlementType()) && StringUtils.isNotBlank(dto.getExternalObjectId()))
                    .map(OrderSettlementResp::getExternalObjectId)
                    .collect(Collectors.toList());

            if (!couponCodes.isEmpty()) {
                CouponUnFreezeReq unFreezeReq = new CouponUnFreezeReq();
                unFreezeReq.setCoupons(couponCodes.stream().map(code -> {
                    return new CouponUnFreezeReq.CouponInfo(){{
                        setCode(code);
                        setMemberId(orderBean.getUserId());
                    }};
                }).collect(Collectors.toList()));
                unFreezeReq.setPartnerId(partnerId);
                CouponBaseResponse<Object> unfreezeResp = couponOnlineClient.unfreeze(unFreezeReq);
                if (!Objects.equals(unfreezeResp.getStatusCode(), 100)) {
                    ApiLog.warnMessage("refundReject 解冻券失败:{}", JSONObject.toJSONString(unfreezeResp));
                }
            }
        }
    }
}
