package com.izouma.dingdong.service.user;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.izouma.dingdong.domain.OrderGoodsSpec;
import com.izouma.dingdong.domain.OrderInfo;
import com.izouma.dingdong.domain.merchant.Merchant;
import com.izouma.dingdong.domain.user.ShoppingCart;
import com.izouma.dingdong.domain.merchant.FullReduction;
import com.izouma.dingdong.domain.merchant.Goods;
import com.izouma.dingdong.domain.merchant.MerchantSettings;
import com.izouma.dingdong.exception.BusinessException;
import com.izouma.dingdong.repo.OrderGoodsSpecRepo;
import com.izouma.dingdong.repo.OrderInfoRepo;
import com.izouma.dingdong.repo.merchant.MerchantRepo;
import com.izouma.dingdong.repo.user.ShoppingCartRepo;
import com.izouma.dingdong.repo.UserRepo;
import com.izouma.dingdong.repo.merchant.FullReductionRepo;
import com.izouma.dingdong.repo.merchant.GoodsRepo;
import com.izouma.dingdong.repo.merchant.MerchantSettingsRepo;
import com.izouma.dingdong.service.rider.DeliveryFeeService;
import com.izouma.dingdong.utils.MapUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

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

@Service
@AllArgsConstructor
public class ShoppingCartService {

    private ShoppingCartRepo     shoppingCartRepo;
    private GoodsRepo            goodsRepo;
    private UserRepo             userRepo;
    private OrderInfoRepo        orderInfoRepo;
    private MerchantSettingsRepo merchantSettingsRepo;
    private FullReductionRepo    fullReductionRepo;
    private OrderGoodsSpecRepo   orderGoodsSpecRepo;
    private DeliveryFeeService   deliveryFeeService;
    private MerchantRepo         merchantRepo;

    //改订单规格
    public void changeOrderSpec(ShoppingCart cart, OrderGoodsSpec orderGoodsSpec) {

        orderGoodsSpec.setShoppingCartId(cart.getId());
        List<OrderGoodsSpec> orderGoodsSpecs = cart.getOrderGoodsSpecs();

        boolean f = true;
        for (OrderGoodsSpec o : orderGoodsSpecs) {//商品id相同
            if (!o.getId().equals(orderGoodsSpec.getId()))
                if (orderGoodsSpec.getGoodsId().equals(o.getGoodsId())) {
                    //且规格id都相同或都为空
                    List<Long> specificationId = orderGoodsSpec.getSpecificationId();
                    List<Long> specificationId1 = o.getSpecificationId();
                    if ((CollUtil.isEmpty(specificationId) && CollUtil.isEmpty(specificationId1)) || specificationId.equals(specificationId1)) {
                        //原有数量加上现在买的数量
                        o.setNum(o.getNum() + orderGoodsSpec.getNum());
                        // o.setGoodsPrice(o.getGoodsPrice().add(orderGoodsSpec.getGoodsPrice()));
                        // o.setGoodsRealPrice(o.getGoodsRealPrice().add(orderGoodsSpec.getGoodsPrice()));

                        orderGoodsSpecRepo.save(o);
                        orderGoodsSpecRepo.deleteById(orderGoodsSpec.getId());
                        //orderGoodsSpecRepo.delete(orderGoodsSpec);
                        f = false;
                        break;
                    }
                }
        }
        if (f) {
            orderGoodsSpecRepo.save(orderGoodsSpec);
        }
    }

    //计算价钱
    public ShoppingCart calculatePrice(Long cartId, Long merchantId) {

        //购物车
        ShoppingCart cart = shoppingCartRepo.findById(cartId).orElseThrow(new BusinessException("无购物车"));
        List<OrderGoodsSpec> specs = cart.getOrderGoodsSpecs();

        //商品总价 商品实际
        BigDecimal goodsTotal = BigDecimal.ZERO;
        BigDecimal goodsReal = BigDecimal.ZERO;

        //满减
        boolean flag = true;
        //包装费
        BigDecimal packingPrice = BigDecimal.ZERO;

        for (OrderGoodsSpec s : specs) {
            //商品总价 商品实际
            goodsTotal = goodsTotal.add(s.getGoodsPrice().multiply(new BigDecimal(s.getNum())));
            goodsReal = goodsReal.add(s.getGoodsRealPrice().multiply(new BigDecimal(s.getNum())));

            Goods goods = goodsRepo.findById(s.getGoodsId()).orElseThrow(new BusinessException("无商品"));
            //满减
            if (!goods.getIsFullReduction()) {
                flag = false;
                cart.setReducedAmount(goodsTotal.subtract(goodsReal));
            }

            //包装费
            if (ObjectUtil.isNotNull(goods.getPackingPrice())) {
                packingPrice = goods.getPackingPrice().multiply(BigDecimal.valueOf(s.getNum()));
            }
        }

        //总价 商品总价+包装费（可参与满减金额）
        BigDecimal total = goodsTotal.add(packingPrice);

        //按商家创建购物车
        // Long merchantId = specs.get(0).getGoods().getMerchantId();
        //商家信息
        MerchantSettings merchant = merchantSettingsRepo.findByMerchantId(merchantId)
                .orElseThrow(new BusinessException("无商户"));

        if (flag) {
            //参与满减
            List<FullReduction> fullReductions = fullReductionRepo.findAllByMerchantId(merchantId);
            fullReductions.sort(Comparator.comparing(FullReduction::getFullAmount));
            for (FullReduction f : fullReductions) {
                if (f.getFullAmount().compareTo(total) <= 0) {
                    //满减金额
                    cart.setFullReduction(f.getMinusAmount());
                    //不是折扣，是满减，就置为减去的金额
                    cart.setReducedAmount(f.getMinusAmount());
                }
            }
        }

        //查找是不是第一次购买
        //List<OrderInfo> userOrders = orderInfoRepo.findAllByUserId(userId);
        List<OrderInfo> userOrdersMerchant = orderInfoRepo.findAllByUserIdAndMerchantId(cart.getUserId(), merchantId);
        //是新用户也是首单
//        if (CollUtil.isEmpty(userOrders)) {
//            shoppingCart.setNewUser(merchant.getNewUser());
//            shoppingCart.setFirstBuy(merchant.getFirstOrder());
//        } else {
        //首单
        if (CollUtil.isEmpty(userOrdersMerchant)) {
            //shoppingCart.setNewUser(BigDecimal.ZERO);
            cart.setFirstBuy(merchant.getFirstOrder());
        } else {
            //非首单设置为0
            //shoppingCart.setNewUser(BigDecimal.ZERO);
            cart.setFirstBuy(BigDecimal.ZERO);
        }
//        }

        //获取配送费
        //cart.setDeliveryAmount(BigDecimal.TEN);

        //需要减去的金额=首单+折扣/满减
        BigDecimal sub2 = cart.getReducedAmount();
        if (ObjectUtil.isNotNull(cart.getFirstBuy())) {
            sub2 = sub2.add(cart.getFirstBuy());
        }

        cart.setGoodsTotal(goodsTotal);
        cart.setReducedAmount(sub2);
        cart.setRealAmount(total.subtract(sub2).add(cart.getDeliveryAmount()));

        return shoppingCartRepo.save(cart);

    }

    //加规格
    public ShoppingCart add(Long userId, OrderGoodsSpec orderGoodsSpec, Double longitude, Double latitude) {
        //按商家创建购物车
        Long merchantId = goodsRepo.findById(orderGoodsSpec.getGoodsId())
                .orElseThrow(new BusinessException("无商品"))
                .getMerchantId();

        //商家信息
        Merchant merchant = merchantRepo.findById(merchantId).orElseThrow(new BusinessException("无商户"));
        //判断是否配送距离内
        Double distance = MapUtils.distance(longitude, latitude, merchant.getLongitude(), merchant.getLatitude());
        if (distance > 3000) {
            throw new BusinessException("超出配送范围");
        }

        //查找是不是第一次购买
        userRepo.findById(userId).orElseThrow(new BusinessException("无用户"));

        //购物车中是否已有
        ShoppingCart shoppingCart = shoppingCartRepo.findByUserIdAndMerchantId(userId, merchantId);
        //加规格
        List<OrderGoodsSpec> specs = CollUtil.newArrayList();
        specs.add(orderGoodsSpec);

        if (ObjectUtil.isNull(shoppingCart)) {
            shoppingCart = ShoppingCart.builder()
                    .merchantId(merchantId)
                    .userId(userId)
                    .goodsTotal(orderGoodsSpec.getGoodsPrice().multiply(BigDecimal.valueOf(orderGoodsSpec.getNum())))
                    .reducedAmount(BigDecimal.ZERO)
                    .orderGoodsSpecs(specs)
                    .packingPrice(BigDecimal.ZERO)
                    .fullReduction(BigDecimal.ZERO)
                    .firstBuy(BigDecimal.ZERO)
                    .enabled(true)
                    .build();
            shoppingCart.setId(-1L);

        } else {
            specs.addAll(shoppingCart.getOrderGoodsSpecs());
            shoppingCart.setOrderGoodsSpecs(specs);
        }

        //配送费计算
        BigDecimal deliveryFee = deliveryFeeService.deliveryFee(merchantId, specs, longitude, latitude);
        shoppingCart.setDeliveryAmount(deliveryFee);

        ShoppingCart save = shoppingCartRepo.save(shoppingCart);

        this.changeOrderSpec(save, orderGoodsSpec);

        return this.calculatePrice(save.getId(), save.getMerchantId());
    }

    //减规格
    public ShoppingCart sub(Long specId) {
        OrderGoodsSpec spec = orderGoodsSpecRepo.findById(specId).orElseThrow(new BusinessException("无订单详情"));
        Long merchantId = spec.getGoods().getMerchantId();
        Long cartId = spec.getShoppingCartId();
        orderGoodsSpecRepo.deleteById(specId);
        //shoppingCartRepo.findById(spec.getShoppingCartId());
        return this.calculatePrice(cartId, merchantId);
    }

    /*
    再来一单
     */
    public ShoppingCart again(Long orderId, Double longitude, Double latitude) {
        OrderInfo orderInfo = orderInfoRepo.findById(orderId).orElseThrow(new BusinessException("无订单"));
        List<OrderGoodsSpec> orderGoodsSpecs = orderInfo.getOrderGoodsSpecs();
        Long userId = orderInfo.getUserId();
        //shoppingCartRepo.findById()
        ShoppingCart cart = new ShoppingCart();
        for (OrderGoodsSpec o : orderGoodsSpecs) {
            OrderGoodsSpec spec = new OrderGoodsSpec();
            BeanUtil.copyProperties(o, spec);
            spec.setOrderInfoId(null);
            spec.setShoppingCartId(null);
            spec.setId(null);
            orderGoodsSpecRepo.save(spec);
            cart = this.add(userId, spec, longitude, latitude);
        }
        return cart;
    }

    /*
    更改数量
     */
    public ShoppingCart changeNum(Long specId, Integer num) {
        OrderGoodsSpec spec = orderGoodsSpecRepo.findById(specId).orElseThrow(new BusinessException("无订单详情"));
        Long merchantId = spec.getGoods().getMerchantId();
        Long cartId = spec.getShoppingCartId();

        spec.setNum(num);
        orderGoodsSpecRepo.save(spec);

        return this.calculatePrice(cartId, merchantId);
    }

}
