package cn.freemud.management.adapter;

import cn.freemud.management.entities.dto.request.console.BizDTO;
import cn.freemud.management.entities.dto.request.console.ConsoleResponseDTO;
import cn.freemud.management.entities.dto.request.console.StoreInfoDTO;
import com.freemud.application.sdk.api.deliverycenter.dto.CreateDeliveryOrderRequestDto;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.entities.v1.ProductBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.OrderType;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.stereotype.Component;

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

@Component
public class DeliverySdkAdapter {
    /**
     * 创建配送单请求对象
     *
     * @param order
     * @param bizDTO
     * @param deliveryCallBackUrl
     * @return
     */
    public CreateDeliveryOrderRequestDto buildDeliveryOrderRequestDto(OrderBeanV1 order
            , ConsoleResponseDTO<BizDTO> bizDTO, String deliveryCallBackUrl) {
        StoreInfoDTO storeInfo = bizDTO.getBizVO().getStoreInfo();
        CreateDeliveryOrderRequestDto deliveryOrderRequestDto = new CreateDeliveryOrderRequestDto();
        deliveryOrderRequestDto.setDepatchWeight(this.getDepatchWeightByOrder(order.getProductList()));
        deliveryOrderRequestDto.setSerialNumber(order.getOtherCode());
        deliveryOrderRequestDto.setOrderId(order.getOid());
        deliveryOrderRequestDto.setOrderRemark(order.getRemark());
        deliveryOrderRequestDto.setOrderTotalAmount(order.getAmount().intValue());
        deliveryOrderRequestDto.setOrderActualAmount(order.getAmount().intValue());
        deliveryOrderRequestDto.setPartnerId(order.getCompanyId());
        deliveryOrderRequestDto.setOrderChannel(order.getSource());
        deliveryOrderRequestDto.setStoreId(storeInfo.getStoreId());
        deliveryOrderRequestDto.setStoreCode(storeInfo.getStoreCode());
        StringBuffer address = new StringBuffer(storeInfo.getCity())
                .append(storeInfo.getProvince())
                .append(storeInfo.getRegion())
                .append(storeInfo.getAddress());
        deliveryOrderRequestDto.setStoreAddress(address.toString());
        deliveryOrderRequestDto.setStoreLng(new BigDecimal(storeInfo.getLongitude()));
        deliveryOrderRequestDto.setStoreLat(new BigDecimal(storeInfo.getLatitude()));
        deliveryOrderRequestDto.setStorePhone(storeInfo.getPhone());
        deliveryOrderRequestDto.setStoreName(order.getShopName());
        deliveryOrderRequestDto.setCityName(storeInfo.getCity());
        deliveryOrderRequestDto.setReceiverName(order.getUserName());
        deliveryOrderRequestDto.setReceiverPrimaryPhone(order.getPhone());
        deliveryOrderRequestDto.setReceiverAddress(order.getAddress());
        deliveryOrderRequestDto.setReceiverLng(BigDecimal.valueOf(order.getLongitude()));
        deliveryOrderRequestDto.setReceiverLat(BigDecimal.valueOf(order.getLatitude()));
        deliveryOrderRequestDto.setOrderTime(new Date(order.getGmtCreate()));
        deliveryOrderRequestDto.setCallbackUrl(deliveryCallBackUrl);
        deliveryOrderRequestDto.setOrderClient(NumberUtils.toInt(order.getOrderClient()));
        // 预约单预计送到时间
        if (order.getGmtExpect() != null && order.getGmtExpect() != 0) {
            deliveryOrderRequestDto.setExpectTime(new Date(order.getGmtExpect()));
        }
        deliveryOrderRequestDto.setIsPre(order.getNewOrderType() == OrderType.RESERVED_EXPRESS.getIndex() ? 1 : 0);
        Optional.ofNullable(order.getProductList())
                .ifPresent(productList ->
                        deliveryOrderRequestDto.setProductInfos(productList.stream()
                                .filter(productBean -> Objects.nonNull(productBean.getPrice()))
                                .filter(productBean -> productBean.getPrice() > 0)
                                .map(productBean -> {
                                    CreateDeliveryOrderRequestDto.DeliveryProductInfo deliveryProductInfo = new CreateDeliveryOrderRequestDto.DeliveryProductInfo();
                                    deliveryProductInfo.setProductCode(productBean.getProductId());
                                    deliveryProductInfo.setProductName(productBean.getProductName());
                                    deliveryProductInfo.setProductNumber(productBean.getNumber());
                                    deliveryProductInfo.setProductPrice(productBean.getPrice().intValue());
                                    return deliveryProductInfo;
                                }).collect(Collectors.toCollection(LinkedList::new))));
        return deliveryOrderRequestDto;
    }

    private BigDecimal getDepatchWeightByOrder(List<ProductBeanV1> productList) {
        if (CollectionUtils.isEmpty(productList)) {
            return new BigDecimal("0.5");
        }
        BigDecimal result = BigDecimal.ZERO;
        productList.forEach(p -> {
            BigDecimal sum = p.getWeight().multiply(new BigDecimal(p.getNumber()));
            if (CollectionUtils.isNotEmpty(p.getComboProduct())) {
                long comboProductSum = p.getComboProduct().stream().mapToLong(value -> value.getWeight().multiply(new BigDecimal(value.getNumber())).longValue()).sum();
                long materialProductSum = p.getMaterialProduct().stream().mapToLong(value -> value.getWeight().multiply(new BigDecimal(value.getNumber())).longValue()).sum();
                long sendProductSum = p.getSendProduct().stream().mapToLong(value -> value.getWeight().multiply(new BigDecimal(value.getNumber())).longValue()).sum();
                BigDecimal otherProductSum = new BigDecimal(comboProductSum + materialProductSum + sendProductSum);
                sum.add(otherProductSum);
            }
            result.add(sum);
        });
        if (result.compareTo(BigDecimal.ZERO) <= 0) {
            return new BigDecimal("0.5");
        }
        // 这里 计算的结果是 g  需要变成 kg 给接口 保留3位小数 后面多余直接舍弃
        return result.divide(new BigDecimal("1000"), 3, BigDecimal.ROUND_DOWN);
    }
}
