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

package com.yami.shop.api.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.*;
import com.yami.shop.bean.order.ConfirmOrderOrder;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
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.checkerframework.checker.units.qual.A;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 确认订单信息时的默认操作
 *
 * @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);
            // 用户地址如果为空，则表示该用户从未设置过任何地址相关信息
            // TODO wangjian 计算积分抵现和分摊，报错
            shopCartItem.setActualTotal(shopCartItem.getProductTotalAmount());
            shopCartOrderDto.setTotalWeight(Arith.add(shopCartOrderDto.getTotalWeight(), Arith.mul(shopCartItem.getWeight(), shopCartItem.getProdCount())));
        }
        //默认走即使配送

//        if (userAddr != null && !Objects.equals(orderParam.getDvyType(), DvyType.FETCH.value())) {
        if (userAddr != null) {
            // 根据配送范围计算配送费，没超出就
            TzTransportDto transport2 = transportManagerService.calculateTransfeeSecondTransport2(shopCartItems.get(0).getShopId(), userAddr, orderParam.getPlatform());
            if (ObjectUtils.isEmpty(transport2)) throw new GlobalException("该渠道下的门店尚未配置可用运费模板");
            switch (orderParam.getPlatform()) {
                case 1://企业用户，计算分单规则
                    if (transport2.getTargetDistance() > transport2.getDistance()) {
                        //超出配送范围使用快递
                        orderParam.setDvyType(DvyType.DELIVERY.value());
                    } else {
                        //即时配送
                        orderParam.setDvyType(DvyType.NOT_DELIVERY.value());
                    }
                    //费用按重量计算,数据是g,现在要按kg计算，20是kg单位
                    double sub = Arith.sub(shopCartOrderDto.getTotalWeight(), Arith.mul(20.0, 1000));
                    transfee = transport2.getFreightFee().doubleValue();
                    if (sub > 0) {
                        //超过重量的安规则计算，累加费用
                        // 假设5元/20kg
                        // (20,40]  (40,60]  (60,80]
                        //   2         3         4
                        //  5*2+5     5*3+5     5*4+5
                        int num = 1;
                        while (sub > (1 << num) * 10) {
                            num++;
                            transfee = Arith.add(transfee, Arith.mul(transfee, num));
                        }
                    }
                    break;
                case 2: //夫妻店，B端只走物流
                    orderParam.setDvyType(DvyType.DELIVERY.value());
                    //TODO 费用待定
                    break;
                case 3: // 市民请集合，C端。只走配送
                    orderParam.setDvyType(DvyType.NOT_DELIVERY.value());
                    //TODO 费用待定
                    break;
            }
        }


        //TODO wangjian 减免运费
        Double freeTransfee = 0.0;
//        List<FreightFeeReduction> feeReductions = freightFeeReductionService.list(new LambdaQueryWrapper<FreightFeeReduction>()
//                        .eq(FreightFeeReduction::getStatus, 1)
//                        .ge(FreightFeeReduction::getEndTime, LocalDateTime.now())
////                .orderByAsc(FreightFeeReduction::getEndTime)
//        );
//        if (!feeReductions.isEmpty()) {
//            for (FreightFeeReduction feeReduction : feeReductions) {
//                freeTransfee += Arith.add(feeReduction.getMoney().doubleValue(), freeTransfee);
//            }
//        }
//        double sub = Arith.sub(transfee, freeTransfee);
//        transfee = Math.signum(sub) < 0 ? 0 : sub;

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


    }
}
