package cn.freemud.adapter;

import cn.freemud.entities.dto.StoreDeliveryInfoDto;
import cn.freemud.entities.dto.UserDeliveryInfoDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.SubtractStockVO;
import cn.freemud.enums.ActivityTypeEnum;
import cn.freemud.enums.OrderAccountType;
import cn.freemud.enums.OrderSourceType;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
import com.freemud.application.sdk.api.promotioncenter.dto.promotion.GoodsStockDTO;
import com.freemud.application.sdk.api.promotioncenter.request.promotion.ActivityUpdateStockRequest;
import com.freemud.sdk.api.assortment.order.enums.OldOrderAccountType;
import com.freemud.sdk.api.assortment.order.enums.QueryDeliveryType;
import com.freemud.sdk.api.assortment.order.enums.QueryOrderType;
import com.freemud.sdk.api.assortment.order.enums.QueryPayType;
import com.freemud.sdk.api.assortment.order.request.order.BaseCreateOrderRequest;
import com.freemud.sdk.api.assortment.order.request.order.CreateOrderAccountRequest;
import com.freemud.sdk.api.assortment.order.request.order.CreateOrderProductRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Component
public class MallOrderAdapter {

    @Autowired
    private OrderAdapter orderAdapter;

    public BaseCreateOrderRequest convent2CreateOrderDto(CreateOrderVo createOrderVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        UserDeliveryInfoDto deliveryInfoDto = createOrderVo.getUserDeliveryInfoDto();
        BaseCreateOrderRequest createOrderDto = getCreateOrderDto(createOrderVo);
        long deliveryAmount = 0;
        if(deliveryInfoDto != null) {
            deliveryAmount = deliveryInfoDto.getRealDeliveryAmount();
        }
        Long packageAmount = shoppingCartGoodsDto.getPackageAmount() == null ? 0L : shoppingCartGoodsDto.getPackageAmount();
        createOrderDto.setAmount(shoppingCartGoodsDto.getTotalAmount() + deliveryAmount + packageAmount);
        // 解析购物车信息
        List<ShoppingCartGoodsDto.CartGoodsDetailDto> cartGoodsDetailDtos = shoppingCartGoodsDto.getProducts();
        List<CreateOrderProductRequest> products = new ArrayList<>();
        ArrayList<CreateOrderAccountRequest> orderAccountDtos = new ArrayList<>();
        // 根据购物车商品信息获取优惠信息
        int orderAccountIndex = 0;
        for (ShoppingCartGoodsDto.CartGoodsDetailDto cartGoodsDetailDto : cartGoodsDetailDtos) {
            Integer qty = cartGoodsDetailDto.getQty();
            if (qty > 0) {
                CreateOrderProductRequest createOrderProductDto = orderAdapter.convent2OrderProduct(cartGoodsDetailDto);
                createOrderProductDto.setIgnoreProductPrice(1);
                products.add(createOrderProductDto);
                if (CollectionUtils.isNotEmpty(cartGoodsDetailDto.getActivityDiscountsDtos())) {
                    createOrderProductDto.setAccounts(orderAdapter.getAccounts(createOrderProductDto, cartGoodsDetailDto.getActivityDiscountsDtos()));
                }
            }
        }
        createOrderDto.setProducts(products);

        if (deliveryAmount > 0) {
            CreateOrderAccountRequest createOrderAccountDto = CreateOrderAccountRequest.builder()
                    .accountId("")
                    .name("配送费")
                    .price(deliveryAmount)
                    .accountType(orderAdapter.getQueryOrderAccountType(OldOrderAccountType.getByCode(OrderAccountType.DELIVERY_AMOUNT.getCode())))
                    .sequence(orderAccountIndex++)
                    .build();
            orderAccountDtos.add(createOrderAccountDto);
        }
        if (packageAmount > 0) {
            CreateOrderAccountRequest createOrderAccountDto = CreateOrderAccountRequest.builder()
                    .accountId("")
                    .name("包装费")
                    .price(packageAmount)
                    .accountType(orderAdapter.getQueryOrderAccountType(OldOrderAccountType.getByCode(OrderAccountType.PACK_AMOUNT.getCode())))
                    .sequence(orderAccountIndex++)
                    .build();
            orderAccountDtos.add(createOrderAccountDto);
        }

        createOrderDto.setAccounts(CollectionUtils.isNotEmpty(orderAccountDtos) ? orderAccountDtos : Collections.emptyList());

        //设置库存扣减
        if (CollectionUtils.isNotEmpty(shoppingCartGoodsDto.getStocks())) {
            List<ActivityUpdateStockRequest.StockBeanDto> stocks = new ArrayList<>();
            for (SubtractStockVO stockVO : shoppingCartGoodsDto.getStocks()) {
                ActivityUpdateStockRequest.StockBeanDto stockBeanDto = new ActivityUpdateStockRequest.StockBeanDto();
                stockBeanDto.setActivityCode(stockVO.getActivityCode());
                stockBeanDto.setActivityStock(stockVO.getActivityStock() == null ? 1 : stockVO.getActivityStock());
                if (CollectionUtils.isNotEmpty(stockVO.getGoodsStock())) {
                    List<GoodsStockDTO> goodsStockDTOS = new ArrayList<>();
                    stockVO.getGoodsStock().forEach(goods -> {
                        GoodsStockDTO goodsStockDTO = new GoodsStockDTO();
                        goodsStockDTO.setBenefitSeq(goods.getBenefitSeq());
                        goodsStockDTO.setGoodsId(goods.getGoodsId());
                        int stock = goods.getStock() == null ? 1 : goods.getStock();
                        goodsStockDTO.setStock(ActivityTypeEnum.TYPE_53.getCode().equals(stockVO.getActivityType()) ? 1 : stock);
                        goodsStockDTOS.add(goodsStockDTO);
                    });
                    stockBeanDto.setGoodsStock(goodsStockDTOS);
                }
                stocks.add(stockBeanDto);
            }
            ActivityUpdateStockRequest activityUpdateStockRequest = new ActivityUpdateStockRequest();
            activityUpdateStockRequest.setStock(stocks);
            createOrderDto.setActivityUpdateStockRequest(activityUpdateStockRequest);
        }
        return createOrderDto;
    }

    public BaseCreateOrderRequest getCreateOrderDto(CreateOrderVo createOrderVo) {
        UserDeliveryInfoDto userDeliveryInfoDto = createOrderVo.getUserDeliveryInfoDto();
        String remark = StringUtils.isNotBlank(createOrderVo.getOrderRemark()) ? createOrderVo.getOrderRemark() : "";
        BaseCreateOrderRequest createOrderDto = new BaseCreateOrderRequest();
        createOrderDto.setCompanyId(createOrderVo.getPartnerId());
        createOrderDto.setShopId(createOrderVo.getShopId());
        createOrderDto.setThirdShopId(createOrderVo.getThirdShopId());
        createOrderDto.setShopName(createOrderVo.getStoreName());
        createOrderDto.setUserId(createOrderVo.getUserId());
        createOrderDto.setUserName(createOrderVo.getUserName());
        createOrderDto.setPhone(userDeliveryInfoDto.getReceiveMobile());
        createOrderDto.setAddress(userDeliveryInfoDto.getReceiveAddress());
        createOrderDto.setLatitude(userDeliveryInfoDto.getUserLatitude());
        createOrderDto.setLongitude(userDeliveryInfoDto.getUserLongitude());
        createOrderDto.setOrderType(QueryOrderType.TAKE_OUT);
        createOrderDto.setPayType(QueryPayType.ONLINE_PAY);
        createOrderDto.setSource(OrderSourceType.MALL.getCode());
        createOrderDto.setSourceName(OrderSourceType.MALL.getDesc());
        createOrderDto.setOrderClientType(OrderClientType.MALL);
        createOrderDto.setRemark(remark);
        createOrderDto.setGmtExpect(null);
        BaseCreateOrderRequest.DeliveryTypeInfo deliveryTypeInfo = new BaseCreateOrderRequest.DeliveryTypeInfo();
        deliveryTypeInfo.setDeliveryType(QueryDeliveryType.THIRD);
        createOrderDto.setAddInfo(deliveryTypeInfo);
        createOrderDto.setAmount(0L);
        createOrderDto.setBarCounter(createOrderVo.getTableNumber());
        createOrderDto.setProvince(userDeliveryInfoDto.getReceiveProvince());
        createOrderDto.setCity(userDeliveryInfoDto.getReceiveCity());
        createOrderDto.setRegion(userDeliveryInfoDto.getReceiveRegion());
        return createOrderDto;
    }

    /**
     * 计算用户收货地址实际配送费
     *
     * @param storeDeliveryInfoDto 门店配送信息
     * @param userLongitude        用户地址经度
     * @param userLatitude         用户地址维度
     * @return
     */
    public Long getUserRealDeliveryAmount(StoreDeliveryInfoDto storeDeliveryInfoDto, String userLongitude, String userLatitude) {
        return 0L;
    }
}
