/*
 * Copyright (c) 2018-2999 广州亚米信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.listener;

import com.yami.shop.bean.app.dto.ShopCartItemDto;
import com.yami.shop.bean.app.dto.ShopCartOrderDto;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.dto.TzTransportDto;
import com.yami.shop.bean.enums.DvyType;
import com.yami.shop.bean.event.ConfirmOrderEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.bean.order.ConfirmOrderOrder;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.delivery.comment.service.TransportManagerService;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.FreightFeeReductionService;
import com.yami.shop.service.ProductService;
import com.yami.shop.service.SkuService;
import com.yami.shop.service.UserAddrService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

/**
 * 确认订单信息时的默认操作
 *
 * @author LGH
 */
@Component("defaultConfirmOrderListener")
@AllArgsConstructor
public class ConfirmOrderListener {

    private final UserAddrService userAddrService;

    private final TransportManagerService transportManagerService;

    private final ProductService productService;

    private final SkuService skuService;

    private final FreightFeeReductionService freightFeeReductionService;

    /**
     * 计算订单金额
     */
    @EventListener(ConfirmOrderEvent.class)
    @Order(ConfirmOrderOrder.DEFAULT)
    public void defaultConfirmOrderEvent(ConfirmOrderEvent event) {
        ShopCartOrderDto shopCartOrderDto = event.getShopCartOrderDto();
        OrderParam orderParam = event.getOrderParam();
        String userId = SecurityUtils.getUser().getUserId();
        UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
        double total = 0.0;
        int totalCount = 0;
        double transfee = 0.0;
        shopCartOrderDto.setTotalWeight(Double.valueOf(0));

        // 重新计算运费时用到
        List<ShopCartItemDto> shopCartItems = event.getShopCartItems();
        for (ShopCartItemDto shopCartItem : event.getShopCartItems()) {
            // 获取商品信息
            Product product = productService.getProductByProdId(shopCartItem.getProdId());
            // 获取sku信息
            Sku sku = skuService.getSkuBySkuId(shopCartItem.getSkuId());
            if (product == null || sku == null) {
                throw new GlobalException("购物车包含无法识别的商品");
            }
            if (product.getStatus() != 1 || sku.getStatus() != 1) {
                throw new GlobalException("商品[" + sku.getProdName() + "]已下架");
            }

            totalCount = shopCartItem.getProdCount() + totalCount;
            total = Arith.add(shopCartItem.getProductTotalAmount(), total);
            // 用户地址如果为空，则表示该用户从未设置过任何地址相关信息
            shopCartItem.setActualTotal(shopCartItem.getProductTotalAmount());
            shopCartOrderDto.setTotalWeight(Arith.add(shopCartOrderDto.getTotalWeight(), Arith.mul(shopCartItem.getWeight(), shopCartItem.getProdCount())));
        }
        //默认走即使配送
        if (userAddr != null) {
            // 根据配送范围计算配送费，没超出就
            TzTransportDto transport2 = transportManagerService.calculateTransfeeSecondTransport2(shopCartItems.get(0).getShopId(), userAddr, orderParam.getChannelId());
            if (ObjectUtils.isEmpty(transport2)) throw new GlobalException("该渠道下的门店尚未配置可用运费模板");
            //企业用户，计算分单规则
            if (transport2.getTargetDistance() > transport2.getDistance()) {
                //超出配送范围使用快递
                orderParam.setDvyType(1);
            } else {
                //即时配送
                orderParam.setDvyType(3);
            }
            //费用按重量计算,数据是g,现在要按kg计算，20是kg单位
            Double totalWeight = shopCartOrderDto.getTotalWeight();
            Double deliveryWeight = Arith.mul(transport2.getWeight(), 1000);
            transfee = calcDeliveryFee(totalWeight, deliveryWeight, new BigDecimal(transport2.getFreightFee().doubleValue())).doubleValue();

        }


        Double freeTransfee = 0.0;
        shopCartOrderDto.setTotal(total);
        shopCartOrderDto.setTotalCount(totalCount);
        shopCartOrderDto.setActualTotal(Arith.add(total, transfee));
        shopCartOrderDto.setTransfee(transfee);
        shopCartOrderDto.setFreeTransfee(freeTransfee);
    }

    public static BigDecimal calcDeliveryFee(Double totalWeight, Double deliveryWeight, BigDecimal unitFare) {
        if (totalWeight == null || totalWeight <= 0 || unitFare == null || unitFare.signum() <= 0) {
            return BigDecimal.ZERO;
        }
        long units = (long) Math.ceil(totalWeight / deliveryWeight);
        return unitFare.multiply(BigDecimal.valueOf(units));
    }

    public static void main(String[] args) {
        System.out.println(calcDeliveryFee(80000.0, 20000.0, BigDecimal.valueOf(5.5)));
    }
}