package com.yc.ship.module.trade.service.ota.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yc.ship.framework.common.exception.ServiceException;
import com.yc.ship.framework.common.lang.Asserts;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.util.collection.CollectionUtils;
import com.yc.ship.framework.common.util.object.ObjectUtils;
import com.yc.ship.framework.tenant.core.context.TenantContextHolder;
import com.yc.ship.module.ota.api.OtaDistributorApi;
import com.yc.ship.module.ota.api.dto.DistributorAgencyPriceDTO;
import com.yc.ship.module.ota.api.dto.DistributorProductRespDTO;
import com.yc.ship.module.ota.api.dto.DistributorRespDTO;
import com.yc.ship.module.product.api.ProductApi;
import com.yc.ship.module.product.api.dto.ProductGroupRespDTO;
import com.yc.ship.module.product.api.dto.ProductSpuRespDTO;
import com.yc.ship.module.product.enums.ProductTypeEnum;
import com.yc.ship.module.product.enums.SpecTypeEnum;
import com.yc.ship.module.trade.api.dto.*;
import com.yc.ship.module.trade.controller.admin.order.vo.order.PayOrderReqVO;
import com.yc.ship.module.trade.controller.admin.order.vo.order.PayOrderRespVO;
import com.yc.ship.module.trade.controller.app.ota.vo.*;
import com.yc.ship.module.trade.convert.order.TradeOrderConvert;
import com.yc.ship.module.trade.dal.dataobject.order.TradeDetailBaseDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeDetailDO;
import com.yc.ship.module.trade.dal.dataobject.order.TradeOrderDO;
import com.yc.ship.module.trade.enums.PayAccountTypeEnum;
import com.yc.ship.module.trade.enums.PayTypeEnum;
import com.yc.ship.module.trade.enums.SellMethodEnum;
import com.yc.ship.module.trade.enums.TradeOrderBindEnum;
import com.yc.ship.module.trade.framework.common.ThreadLocalUtil;
import com.yc.ship.module.trade.service.order.TradeOrderRepositoryService;
import com.yc.ship.module.trade.service.order.TradeOrderService;
import com.yc.ship.module.trade.service.order.bo.TradeDetailBO;
import com.yc.ship.module.trade.service.order.bo.TradeVisitorBO;
import com.yc.ship.module.trade.service.ota.OtaInnerService;
import com.yc.ship.module.trade.service.pay.TradeOrderPayService;
import com.yc.ship.module.trade.service.refund.TradeRefundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.yc.ship.module.trade.enums.ApiConstants.*;
import static com.yc.ship.module.trade.enums.ErrorCodeConstants.*;
import static com.yc.ship.module.trade.enums.TravelhubDictTypeConstants.*;

/**
 * &#064;Description ：ota内部标准接口实现
 * &#064;Author ：qsl
 * &#064;Date ：2025/6/17 20:50
 */
@Service
@Slf4j
public class OtaInnerServiceImpl implements OtaInnerService {

    @Resource
    private TradeOrderService tradeOrderService;
    @Resource
    private TradeOrderPayService tradeOrderPayService;
    @Resource
    private TradeOrderRepositoryService tradeOrderRepositoryService;
    @Resource
    private OtaDistributorApi otaDistributorApi;
    @Resource
    private ProductApi productApi;
    @Resource
    private TradeRefundService tradeRefundService;

    @Override
    public CommonResult<OtaStandardOrderRespVO> createOrder(OtaInnerOrderVO otaInnerOrderVO, DistributorRespDTO otaDistributeDTO) {
        Asserts.isTrue(otaDistributeDTO.getIsUse() == YES,"分销商未启用:{}",otaDistributeDTO.getId());
        boolean oldIgnore = TenantContextHolder.isIgnore();
        try{
            //设置当前租户为平台租户
            TenantContextHolder.setTenantId(otaDistributeDTO.getTenantId());
            TenantContextHolder.setIgnore(false);
            //设置下单信息
            TradeOrderCreateReqDTO reqDTO = convert(otaInnerOrderVO,otaDistributeDTO);
            //绑定改签关系
            bindOrderChange(reqDTO);
            //绑定增加订单
            bindOrderAdd(reqDTO);
//            log.info("内部分销向平台下单开始："+reqDTO.getExternalOrderNo());
            CommonResult<TradeOrderRespDTO> resp = tradeOrderService.createOrder(reqDTO);
//            log.info("内部分销向平台下单结束："+resp.getMsg());
            if(resp.isError()){
                return CommonResult.error(resp);
            }
            return CommonResult.success(new OtaStandardOrderRespVO().setOtaOrderId(otaInnerOrderVO.getOtaOrderId())
                    .setSupplierOrderNo(resp.getData().getOrderNo()));
        }catch (ServiceException e){
            log.error("ota内部标准下单失败：",e);
            return CommonResult.error(e);
        }catch (Exception e){
            log.error("ota内部标准下单失败：",e);
            return CommonResult.error(OTA_INNER_ORDER_CREATE_FAIL);
        }finally {
            TenantContextHolder.setTenantId(otaDistributeDTO.getAccountTenantId());
            TenantContextHolder.setIgnore(oldIgnore);
        }
    }

    @Override
    public CommonResult<OtaStandardOrderPayRespVO> payOrder(OtaInnerOrderPayVO otaInnerOrderPayVO, DistributorRespDTO otaDistributeDTO) {
        boolean oldIgnore = TenantContextHolder.isIgnore();
        try{
            Asserts.isTrue(otaDistributeDTO.getIsUse() == YES,"分销商未启用:{}",otaDistributeDTO.getId());
            //设置当前租户为平台租户
            TenantContextHolder.setTenantId(otaDistributeDTO.getTenantId());
            TenantContextHolder.setIgnore(false);
            //设置下单信息
            PayOrderReqVO payOrderReqVO = convertToPayVO(otaInnerOrderPayVO,otaDistributeDTO);

            CommonResult<PayOrderRespVO> resp = tradeOrderPayService.payOrder(payOrderReqVO);
            if(resp.isError()){
                return CommonResult.error(resp);
            }
            //根据订单ID返回券码信息
            List<TradeVisitorBO> tradeVisitorBOList =  tradeOrderRepositoryService.getVisitorVoucherListByOrderId(resp.getData().getOrderId());
            List<OtaVoucherVO> voucherList = TradeOrderConvert.INSTANCE.convertToVoucherList(tradeVisitorBOList);
            return CommonResult.success(new OtaStandardOrderPayRespVO().setOtaOrderId(resp.getData().getOrderId().toString())
                    .setSupplierOrderNo(otaInnerOrderPayVO.getSupplierOrderNo()).setVoucherList(voucherList));
        }catch (ServiceException e){
            log.error("ota内部标准下单支付失败：",e);
            return CommonResult.error(e);
        }catch (Exception e){
            log.error("ota内部标准下单支付失败：",e);
            return CommonResult.error(OTA_INNER_ORDER_CREATE_FAIL);
        }finally {
            TenantContextHolder.setTenantId(otaDistributeDTO.getAccountTenantId());
            TenantContextHolder.setIgnore(oldIgnore);
        }
    }

    @Override
    public CommonResult<OtaStandardRefundRespVO> refund(OtaInnerRefundVO otaInnerRefundVO, DistributorRespDTO otaDistributeDTO) {
        boolean oldIgnore = TenantContextHolder.isIgnore();
        try{
            Asserts.isTrue(otaDistributeDTO.getIsUse() == YES,"分销商未启用:{}",otaDistributeDTO.getId());
            //设置当前租户为平台租户
            TenantContextHolder.setTenantId(otaDistributeDTO.getTenantId());
            TenantContextHolder.setIgnore(false);
            //设置下单信息
            TradeRefundCreateReqDTO reqDTO = convert(otaInnerRefundVO,otaDistributeDTO);
            CommonResult<TradeRefundRespDTO> resp = tradeRefundService.refund(reqDTO);

            OtaStandardRefundRespVO otaStandardRefundRespVO = new OtaStandardRefundRespVO().setOtaRefundId(otaInnerRefundVO.getOtaRefundId());
            if(resp.isError()){
                CommonResult<OtaStandardRefundRespVO> result = CommonResult.error(resp);
                if(resp.getData()!=null){
                    result.setData(otaStandardRefundRespVO.setSupplierRefundId(resp.getData().getRefundId().toString()));
                }
                return result;
            }
            return CommonResult.success(otaStandardRefundRespVO.setSupplierRefundId(resp.getData().getRefundId().toString()));
        }catch (ServiceException e){
            log.error("ota内部标准退款失败：",e);
            return CommonResult.error(e);
        }catch (Exception e){
            log.error("ota内部标准退款失败：",e);
            return CommonResult.error(OTA_INNER_REFUND_FAIL);
        }finally {
            TenantContextHolder.setTenantId(otaDistributeDTO.getAccountTenantId());
            TenantContextHolder.setIgnore(oldIgnore);
        }
    }

    @Override
    public CommonResult<?> bindVisitor(OtaInnerBindVisitorVO otaInnerBindVisitorVO, DistributorRespDTO otaDistributeDTO) {
        Asserts.isTrue(otaDistributeDTO.getIsUse() == YES,"分销商未启用:{}",otaDistributeDTO.getId());
        boolean oldIgnore = TenantContextHolder.isIgnore();
        try{
            //设置当前租户为平台租户
            TenantContextHolder.setTenantId(otaDistributeDTO.getTenantId());
            TenantContextHolder.setIgnore(false);
            //设置绑定信息
            TradeOrderDO tradeOrderDO = tradeOrderRepositoryService.getOrderByNo(otaInnerBindVisitorVO.getSupplierOrderNo());

            TradeModifyVisitorReqDTO reqDTO = new TradeModifyVisitorReqDTO();
            reqDTO.setOrderId(tradeOrderDO.getId());

            List<TradeVisitorBO> visitorBOList = tradeOrderRepositoryService.getVisitorVoucherListByOrderId(tradeOrderDO.getId());
            List<TradeModifyVisitorReqDTO.VisitorItem> visitorBindList = otaInnerBindVisitorVO.getBindItemList().stream().map(bindItem -> {
                List<TradeVisitorBO> bindVisitorList = visitorBOList.stream().filter(visitorBO -> {
                    return ObjectUtil.equal(bindItem.getVoucherCode(), visitorBO.getVoucherCode());
                }).collect(Collectors.toList());
                Asserts.isTrue(CollUtil.isNotEmpty(bindVisitorList), "补录未找到匹配的游客信息", bindItem.getVoucherCode());
                Integer quantityOfOne = bindVisitorList.get(0).getQuantityOfOne();
                List<TradeModifyVisitorReqDTO.VisitorItem> visitorItemList = new ArrayList<>();
                if (quantityOfOne != null) {
                    for (Integer i = 0; i < quantityOfOne; i++) {
                        if (i >= bindItem.getVisitorList().size()) {
                            break;
                        }
                        TradeVisitorBO tradeVisitorBO = bindVisitorList.get(i);
                        TradeOrderCreateReqDTO.Visitor visitor = bindItem.getVisitorList().get(i);
                        TradeModifyVisitorReqDTO.VisitorItem visitorItem = new TradeModifyVisitorReqDTO.VisitorItem();
                        visitorItem.setVisitorId(tradeVisitorBO.getId());
                        visitorItem.setDetailId(tradeVisitorBO.getDetailId());
                        visitorItem.setName(visitor.getName());
                        visitorItem.setMobile(visitor.getMobile());
                        visitorItem.setCredentialNo(visitor.getCredentialNo());
                        visitorItem.setCredentialType(visitor.getCredentialType());
                        visitorItemList.add(visitorItem);
                    }
                }
                return visitorItemList;
            }).flatMap(Collection::stream).collect(Collectors.toList());

            reqDTO.setVisitorList(visitorBindList);
            CommonResult<?> resp = tradeOrderService.modifyVisitor(reqDTO);
            return resp;
        }catch (ServiceException e){
            log.error("ota内部标准补录失败：",e);
            return CommonResult.error(e);
        }catch (Exception e){
            log.error("ota内部标准补录失败：",e);
            return CommonResult.error(OTA_INNER_REFUND_FAIL);
        }finally {
            TenantContextHolder.setTenantId(otaDistributeDTO.getAccountTenantId());
            TenantContextHolder.setIgnore(oldIgnore);
        }
    }

    @Override
    public CommonResult<?> cancelOrder(String supplierOrderNo, DistributorRespDTO otaDistributeDTO) {
        Asserts.isTrue(otaDistributeDTO.getIsUse() == YES,"分销商未启用:{}",otaDistributeDTO.getId());
        boolean oldIgnore = TenantContextHolder.isIgnore();
        try{
            //设置当前租户为平台租户
            TenantContextHolder.setTenantId(otaDistributeDTO.getTenantId());
            TenantContextHolder.setIgnore(false);
            //设置绑定信息
            TradeOrderDO tradeOrderDO = tradeOrderRepositoryService.getOrderByNo(supplierOrderNo);
            return tradeOrderPayService.cancelOrder(tradeOrderDO.getId());
        }catch (ServiceException e){
            log.error("ota内部订单取消：",e);
            return CommonResult.error(e);
        }catch (Exception e){
            log.error("ota内部订单取消：",e);
            return CommonResult.error(OTA_INNER_CANCEL_FAIL);
        }finally {
            TenantContextHolder.setTenantId(otaDistributeDTO.getAccountTenantId());
            TenantContextHolder.setIgnore(oldIgnore);
        }
    }

    private TradeOrderCreateReqDTO convert(OtaInnerOrderVO otaInnerOrderVO,DistributorRespDTO otaDistributeDTO){
        TradeOrderCreateReqDTO reqDTO = new TradeOrderCreateReqDTO();
        reqDTO.setExternalOrderNo(otaInnerOrderVO.getOtaOrderId());
        reqDTO.setExternalOriginOrderNo(otaInnerOrderVO.getOtaOriginOrderNo());

        TradeOrderCreateReqDTO.OrderProperty orderProperty = new TradeOrderCreateReqDTO.OrderProperty();
        orderProperty.setSellMethod(SellMethodEnum.OTC.getType());
        orderProperty.setSourceName(otaDistributeDTO.getName());
        orderProperty.setSourceId(otaDistributeDTO.getId().toString());
        orderProperty.setStoreId(otaInnerOrderVO.getStoreId());
        orderProperty.setStoreName(otaInnerOrderVO.getStoreName());
        reqDTO.setOrderProperty(orderProperty);
        reqDTO.setOrderUser(otaInnerOrderVO.getOrderUser());

        //获取产品信息,使用平台分销时设置的价格
        DistributorProductRespDTO distributorProduct = otaDistributorApi.getCalendarProductById(Long.parseLong(otaInnerOrderVO.getProductId()), DateUtil.formatDate(otaInnerOrderVO.getTravelDate())).getCheckedData();
        Long productId = distributorProduct.getProductId();

        ProductSpuRespDTO product = productApi.getCalendarProduct(productId, DateUtil.formatDate(otaInnerOrderVO.getTravelDate()),otaInnerOrderVO.getRoutePlanId()).getCheckedData();
        if(product.getOwnThisPlan()!=null && !product.getOwnThisPlan()){
            //说明这个时间方案不是这个产品的，可以忽略
            otaInnerOrderVO.setRoutePlanId(null);
        }
        if(ObjectUtil.equal(product.getProductType(), ProductTypeEnum.Hotel.getValue()) && otaInnerOrderVO.getHotelBooking()!=null){
            //如果是酒店产品
            long day = DateUtil.betweenDay(otaInnerOrderVO.getHotelBooking().getCheckinTime(),otaInnerOrderVO.getHotelBooking().getCheckoutTime(),true);
            if(day>1){
                //获取区间日历价
                distributorProduct = otaDistributorApi.getAgencyCalendarRangeProductById(Long.parseLong(otaInnerOrderVO.getProductId()), DateUtil.formatDate(otaInnerOrderVO.getHotelBooking().getCheckinTime())
                        ,DateUtil.formatDate(otaInnerOrderVO.getHotelBooking().getCheckoutTime())).getCheckedData();
            }
        }

        List<TradeOrderCreateReqDTO.OrderItem> itemlList = new ArrayList<>();
        TradeOrderCreateReqDTO.OrderItem orderItem = new TradeOrderCreateReqDTO.OrderItem();
        orderItem.setProductId(productId.toString());
        orderItem.setProductType(PRODUCT_BASE_TYPE_SELF);
        orderItem.setUseDate(otaInnerOrderVO.getTravelDate());
        orderItem.setHotelBooking(otaInnerOrderVO.getHotelBooking());
        BigDecimal totalAmount = new BigDecimal(0);
        int totalNum =0;
        for (TradeOrderCreateReqDTO.OrderDetail orderDetail : otaInnerOrderVO.getDetailList()) {
            //设置结算金额
            calculateTradeDetailPrice(orderDetail,product,distributorProduct,otaInnerOrderVO);
            totalAmount = totalAmount.add(orderDetail.getPrice().multiply(new BigDecimal(orderDetail.getCount())).setScale(2, RoundingMode.HALF_UP));
            orderDetail.setProductType(PRODUCT_BASE_TYPE_SELF);
            totalNum += orderDetail.getCount();
        }
        orderItem.setDetailList(otaInnerOrderVO.getDetailList());
        itemlList.add(orderItem);
        reqDTO.setItemlList(itemlList);
        reqDTO.setAmount(totalAmount);
        reqDTO.setPayAmount(totalAmount);
        reqDTO.setTravelDate(otaInnerOrderVO.getTravelDate());
        reqDTO.setRoutePlanId(otaInnerOrderVO.getRoutePlanId());
        reqDTO.setRemark(otaInnerOrderVO.getRemark());
        reqDTO.setIsMarketing(otaInnerOrderVO.getIsMarketing());
        reqDTO.setIsTimePay(otaInnerOrderVO.getIsTimePay());
        reqDTO.setIsMarketingUse(otaInnerOrderVO.getIsMarketingUse());
        reqDTO.setAgencyGroupId(otaInnerOrderVO.getAgencyGroupId());
        reqDTO.setAreaManagerId(otaInnerOrderVO.getAreaManagerId());
        if(ObjectUtil.equal(product.getProductType(), ProductTypeEnum.Goods.getValue()) && otaInnerOrderVO.getDeliveryInfo()!=null){
            reqDTO.setDeliveryInfo(otaInnerOrderVO.getDeliveryInfo());
        }
        if(ObjectUtil.equal(otaInnerOrderVO.getIsChange(),YES)){
            reqDTO.setIsChange(otaInnerOrderVO.getIsChange());
            reqDTO.setOrderId(IdWorker.getId());
            TradeOrderDO mainOrder = tradeOrderRepositoryService.getOrderByNo(otaInnerOrderVO.getMainOrderNo());
            Asserts.isTrue(mainOrder!=null,"平台未找到对应订单信息{}",otaInnerOrderVO.getMainOrderNo());
            reqDTO.setMainOrderId(mainOrder.getId());
        }
        if(ObjectUtil.equal(otaInnerOrderVO.getIsAddOrder(),YES)){
            reqDTO.setIsAddOrder(YES);
            reqDTO.setOrderId(IdWorker.getId());
            TradeOrderDO mainOrder = tradeOrderRepositoryService.getOrderByNo(otaInnerOrderVO.getMainOrderNo());
            Asserts.isTrue(mainOrder!=null,"平台未找到对应订单信息{}",otaInnerOrderVO.getMainOrderNo());
            reqDTO.setMainOrderId(mainOrder.getId());
        }

//        //验证分销产品库存
//        StockDistributorDeductReqDTO deductReqDTO = new StockDistributorDeductReqDTO();
//        deductReqDTO.setDistributorProductId(Long.parseLong(otaInnerOrderVO.getProductId()));
//        deductReqDTO.setNum(totalNum);
//        deductReqDTO.setUseDate(otaInnerOrderVO.getTravelDate());
//        stockApi.deductDistributorStock(deductReqDTO).getCheckedData();

        return reqDTO;
    }
    private void calculateTradeDetailPrice(TradeOrderCreateReqDTO.OrderDetail orderDetail,ProductSpuRespDTO product,DistributorProductRespDTO distributorProduct,OtaInnerOrderVO otaInnerOrderVO){
        BigDecimal price = new BigDecimal(0);
        Asserts.isTrue(CollUtil.isNotEmpty(distributorProduct.getDistributorAgencyPriceList()),"旅行社分销商产品未设置价格，请先设置");
        //产品价格逻辑：skuId的价格（关联产品 + 通用必须） + 选择的多规格产品 + 选择的非必选产品
        //筛选sku关联产品，此类产品必选
        if(ObjectUtil.equal(product.getProductType(), ProductTypeEnum.Hotel.getValue()) && otaInnerOrderVO.getHotelBooking()!=null){
            //如果是酒店产品
            long day = DateUtil.betweenDay(otaInnerOrderVO.getHotelBooking().getCheckinTime(),otaInnerOrderVO.getHotelBooking().getCheckoutTime(),true);
            if(day>1){
                Date stDate = otaInnerOrderVO.getHotelBooking().getCheckinTime();
                while (stDate.compareTo(otaInnerOrderVO.getHotelBooking().getCheckoutTime())<=0) {
                    price = price.add(doCalculateTradeDetailPrice(orderDetail, product, distributorProduct, stDate));
                    stDate = DateUtil.offsetDay(stDate, 1);
                }
            }else{
                price = doCalculateTradeDetailPrice(orderDetail, product, distributorProduct, null);
                //设置明细价格
                setOrderDetailPrice(orderDetail, otaInnerOrderVO.getTravelDate(), price);
            }

            orderDetail.setPrice(price);
            orderDetail.setOriginPrice(price);

        }else{
            price = doCalculateTradeDetailPrice(orderDetail, product, distributorProduct, null);

            orderDetail.setPrice(price);
            orderDetail.setOriginPrice(price);
        }

    }

    private BigDecimal doCalculateTradeDetailPrice(TradeOrderCreateReqDTO.OrderDetail orderDetail, ProductSpuRespDTO product,DistributorProductRespDTO distributorProduct, Date useDate){

        BigDecimal price = new BigDecimal(0);
        //产品价格逻辑：skuId的价格（关联产品 + 通用必须） + 选择的多规格产品 + 选择的非必选产品
        //筛选sku关联产品，此类产品必选
        DistributorAgencyPriceDTO distributorAgencyPriceDTO = distributorProduct.getDistributorAgencyPriceList().stream().filter(item -> {
            if(useDate == null){
                return  ObjectUtil.equal(orderDetail.getSpecType(), item.getSpecType());
            }else {
                return  ObjectUtil.equal(orderDetail.getSpecType(), item.getSpecType()) && DateUtil.isSameDay(useDate,item.getUseDate());
            }
        }).findFirst().orElse(null);
        //现在可以只下非必选的产品
//        Asserts.isTrue(distributorAgencyPriceDTO!=null,"分销商产品当前规格未设置价格{},{}",orderDetail.getSpecType(),distributorProduct.getId());
        Collection<TradeOrderCreateReqDTO.OrderDetailBase> otherDetailBaseList;
        if(distributorAgencyPriceDTO!=null){
            List<ProductGroupRespDTO> skuProductGroupList = product.getProductGroupList().stream().filter(item ->distributorAgencyPriceDTO.getProductSkuId()!=null && ObjectUtil.equal(distributorAgencyPriceDTO.getProductSkuId(), item.getSkuId())).collect(Collectors.toList());

            if(CollUtil.isNotEmpty(skuProductGroupList)){
                //sku关联的基础产品和必选的通用产品，使用sku的价格
                List<TradeOrderCreateReqDTO.OrderDetailBase> skuDetailBaseList = new ArrayList<>();
                for (ProductGroupRespDTO productGroupRespDTO : skuProductGroupList) {
                    TradeOrderCreateReqDTO.OrderDetailBase  detailBase = getDetailBase(orderDetail.getDetailBaseList(),productGroupRespDTO);
                    Asserts.isTrue(detailBase!=null,"产品内的基础产品未在下单参数中{}",productGroupRespDTO.getProductBaseId());
                    skuDetailBaseList.add(detailBase);
                }
                //加上sku的价格
                price = price.add(distributorAgencyPriceDTO.getSalePrice());
                //排除sku的产品
                otherDetailBaseList = CollUtil.subtract(orderDetail.getDetailBaseList(), skuDetailBaseList);

            }else{
                //历史数据产品未关联skuId的情况 ，临时适配
                otherDetailBaseList =orderDetail.getDetailBaseList();
            }
        }else{
            //非必选产品
            otherDetailBaseList =orderDetail.getDetailBaseList();
        }

        for (TradeOrderCreateReqDTO.OrderDetailBase orderDetailBase : otherDetailBaseList) {
            ProductGroupRespDTO productGroup = getDetailBase(orderDetailBase,product.getProductGroupList());
            Asserts.isTrue(productGroup!=null,"平台产品发生变化，请重新下单");
            if(ObjectUtil.equal(productGroup.getSpecType(), SpecTypeEnum.COMMON.getType())  && productGroup.getNeedChoose() == YES){
                //通用产品，又是必须得，此处过滤，因为后台设置价格的时候是包含了此种产品的
                continue;
            }
            price = price.add(productGroup.getSalePrice());
        }

        if(useDate!=null){
            //设置明细价格
            setOrderDetailPrice(orderDetail, useDate, price);
        }

        return price;
    }

    private void setOrderDetailPrice(TradeOrderCreateReqDTO.OrderDetail orderDetail,Date useDate,BigDecimal price){
        if(orderDetail.getDetailPriceList() == null){
            orderDetail.setDetailPriceList(new ArrayList<>());
        }
        TradeOrderCreateReqDTO.DetailPrice detailPrice = new TradeOrderCreateReqDTO.DetailPrice();
        detailPrice.setUseDate(useDate);
        detailPrice.setSalePrice(price);
        detailPrice.setOriginPrice(price);

        orderDetail.getDetailPriceList().add(detailPrice);
    }

    private ProductGroupRespDTO getDetailBase(TradeOrderCreateReqDTO.OrderDetailBase orderDetailBase,List<ProductGroupRespDTO> productGroupList){
        return productGroupList.stream().filter(item-> ObjectUtil.equal(item.getProductBaseId(),orderDetailBase.getProductBaseId())
                && ObjectUtil.equal(item.getSpecificationId(),orderDetailBase.getSpecificationId())
                && ObjectUtil.equal(item.getSpecType(),orderDetailBase.getSpecType())).findFirst().orElse(null);
    }

    private TradeOrderCreateReqDTO.OrderDetailBase getDetailBase(List<TradeOrderCreateReqDTO.OrderDetailBase> orderDetailBaseList,ProductGroupRespDTO productGroup){
        return orderDetailBaseList.stream().filter(item-> ObjectUtil.equal(item.getProductBaseId(),productGroup.getProductBaseId())
                && ObjectUtil.equal(item.getSpecificationId(),productGroup.getSpecificationId())
                && ObjectUtil.equal(item.getSpecType(),productGroup.getSpecType())).findFirst().orElse(null);
    }


    private PayOrderReqVO convertToPayVO(OtaInnerOrderPayVO otaInnerOrderPayVO,DistributorRespDTO otaDistributeDTO){
        //根据订单编号查询订单
        TradeOrderDO tradeOrderDO = tradeOrderRepositoryService.getOrderByNo(otaInnerOrderPayVO.getSupplierOrderNo());
        PayOrderReqVO payOrderReqVO = new PayOrderReqVO();
        payOrderReqVO.setAccountId(otaDistributeDTO.getId().toString());
        if(otaDistributeDTO.getType() == 1){
            //ota
            payOrderReqVO.setAccountType(PayAccountTypeEnum.OTA.getType());
        }else if(otaDistributeDTO.getType() == 2){
            //旅行社
            payOrderReqVO.setAccountType(PayAccountTypeEnum.OTC.getType());
        }
        payOrderReqVO.setOrderId(tradeOrderDO.getId());
        payOrderReqVO.setPayAmount(tradeOrderDO.getPayAmount());
        //正常支付
        if(otaInnerOrderPayVO.getPayType()!=null){
            //指定了支付方式
            payOrderReqVO.setPayType(otaInnerOrderPayVO.getPayType());
            payOrderReqVO.setCanChangePayType(NO);
        }else {
            //预付款>授信
            Object[] payTypes = otaDistributeDTO.getPayType().split(",");
            if(CollectionUtils.containsAny("1",payTypes)){
                payOrderReqVO.setPayType(PayTypeEnum.ADVANCE_PAYMENT.getType());
            }else if(CollectionUtils.containsAny("2",payTypes)){
                payOrderReqVO.setPayType(PayTypeEnum.CREDIT_GRANTING.getType());
            }
        }

        return payOrderReqVO;
    }

    private TradeRefundCreateReqDTO convert(OtaInnerRefundVO otaInnerRefundVO,DistributorRespDTO otaDistributeDTO){

        //获取订单
        TradeOrderDO tradeOrderDO = tradeOrderRepositoryService.getOrderByNo(otaInnerRefundVO.getSupplierOrderId());
        List<String> voucherCodeList = otaInnerRefundVO.getRefundVoucherList().stream().map(OtaInnerRefundVoucherVO::getVoucherCode).collect(Collectors.toList());
        List<TradeDetailBO> tradeDetailBOList = tradeOrderRepositoryService.getTradeDetailWithBase(tradeOrderDO.getId(), null, voucherCodeList);
        Asserts.isTrue(otaInnerRefundVO.getRefundVoucherList().size() == tradeDetailBOList.size(),"退款券码数量与实际数量不符，需退{},实际{}",otaInnerRefundVO.getRefundVoucherList().size(),tradeDetailBOList.size());
        TradeRefundCreateReqDTO reqDTO = new TradeRefundCreateReqDTO();
        reqDTO.setOrderId(tradeOrderDO.getId());
        reqDTO.setOtaRefundNo(otaInnerRefundVO.getOtaRefundId());
        //暂时如果是改签退款,二次确认退款才传递
        if(ObjectUtils.equalsAny(otaInnerRefundVO.getRefundMethod(),REFUND_METHOD_CHANGE_ORDER,REFUND_METHOD_CONFIRM_ORDER)){
            reqDTO.setRefundMethod(otaInnerRefundVO.getRefundMethod());
        }else {
            reqDTO.setRefundMethod(REFUND_METHOD_NORMAL);
        }
        if(otaDistributeDTO.getType() == 1){
            //ota
            reqDTO.setRefundChannel(SellMethodEnum.OTA.getType());
        }else if(otaDistributeDTO.getType() == 2){
            //旅行社
            reqDTO.setRefundChannel(SellMethodEnum.OTC.getType());
        }
        reqDTO.setRefundUser(otaDistributeDTO.getId());
        BigDecimal totalAmount = new BigDecimal(0);
        List<TradeRefundCreateReqDTO.RefundItem> itemlList = new ArrayList<>();
        for (TradeDetailBO tradeDetailBO : tradeDetailBOList) {
            TradeRefundCreateReqDTO.RefundItem refundItem = new TradeRefundCreateReqDTO.RefundItem();
            refundItem.setRefundAmount(tradeDetailBO.getActualPrice());
            refundItem.setOrderDetailId(tradeDetailBO.getId());
            totalAmount = totalAmount.add(tradeDetailBO.getActualPrice());
            OtaInnerRefundVoucherVO innerRefundVoucherVO =  otaInnerRefundVO.getRefundVoucherList().stream().filter(innerRefundVoucherItem -> ObjectUtil.equal(innerRefundVoucherItem.getVoucherCode(),tradeDetailBO.getVoucherCode())).findFirst().orElse(null);
            Asserts.isTrue(innerRefundVoucherVO!=null,"退款券码不正确",tradeDetailBO.getVoucherCode());
            //退票订单基础信息,相等说明退全票
            if(innerRefundVoucherVO.getProductBaseList().size() != tradeDetailBO.getTradeDetailBaseList().size()){
                List<TradeRefundCreateReqDTO.RefundSubItem> detailList = new ArrayList<>();
                for (Long productBaseId : innerRefundVoucherVO.getProductBaseList()) {
                    TradeDetailBaseDO tradeDetailBaseDO = tradeDetailBO.getTradeDetailBaseList().stream().filter(tradeDetailBaseDOItem -> ObjectUtil.equal(productBaseId, tradeDetailBaseDOItem.getProductBaseId())).findFirst().orElse(null);
                    Asserts.isTrue(tradeDetailBaseDO!=null,"向平台退款子票数据不存在{}",productBaseId);
                    TradeRefundCreateReqDTO.RefundSubItem refundSubItem = new TradeRefundCreateReqDTO.RefundSubItem();
                    refundSubItem.setRefundAmount(tradeDetailBaseDO.getPrice());
                    refundSubItem.setOrderDetailBaseId(tradeDetailBaseDO.getId());
                    detailList.add(refundSubItem);
                }
                refundItem.setDetailList(detailList);
            }
            itemlList.add(refundItem);
        }
        reqDTO.setRefundAmount(totalAmount);
        reqDTO.setItemlList(itemlList);
        return reqDTO;
    }

    private void bindOrderChange(TradeOrderCreateReqDTO createReqDTO){
        if(ObjectUtil.notEqual(createReqDTO.getIsChange(),YES) || createReqDTO.getMainOrderId() == null){
            return;
        }

        if(CollUtil.isNotEmpty(ThreadLocalUtil.getChangeDetailList())){
            List<Long> changeDetailIdList = ThreadLocalUtil.getChangeDetailList();
            List<TradeDetailDO> tradeDetailDOList = tradeOrderRepositoryService.getPlatDetailByDetailIds(changeDetailIdList,createReqDTO.getMainOrderId());
            Asserts.isTrue(changeDetailIdList.size() == tradeDetailDOList.size(),"改签数据不匹配，平台改签绑定失败");
            List<Long> platChangeDetailIdList = tradeDetailDOList.stream().map(TradeDetailDO::getId).collect(Collectors.toList());
            tradeOrderService.bindChangeOrder(platChangeDetailIdList, createReqDTO.getOrderId(), createReqDTO.getMainOrderId());
        }else{
            tradeOrderService.bindChangeOrder(null, createReqDTO.getOrderId(), createReqDTO.getMainOrderId());
        }

    }

    private void bindOrderAdd(TradeOrderCreateReqDTO createReqDTO){
        if(ObjectUtil.notEqual(createReqDTO.getIsAddOrder(),YES) || createReqDTO.getMainOrderId() == null){
            return;
        }

        TradeBindOrderReqDTO tradeBindOrderReqDTO = new TradeBindOrderReqDTO();
        tradeBindOrderReqDTO.setBindId(createReqDTO.getOrderId());
        tradeBindOrderReqDTO.setOrderId(createReqDTO.getMainOrderId());
        tradeBindOrderReqDTO.setType(TradeOrderBindEnum.ADD_ORDER.getType());
        tradeOrderService.bindOrder(tradeBindOrderReqDTO);
    }
}
