package co.yixiang.yshop.module.cart.service.storecart;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.enums.OrderInfoEnum;
import co.yixiang.yshop.framework.common.enums.ShopCommonEnum;
import co.yixiang.yshop.framework.common.exception.ErrorCode;
import co.yixiang.yshop.module.cart.convert.storecart.StoreCartConvert;
import co.yixiang.yshop.module.cart.dal.dataobject.storecart.StoreCartDO;
import co.yixiang.yshop.module.cart.dal.mysql.storecart.StoreCartMapper;
import co.yixiang.yshop.module.cart.enums.CartTypeEnum;
import co.yixiang.yshop.module.product.api.product.ProductApi;
import co.yixiang.yshop.module.product.controller.app.cart.vo.AppStoreCartQueryVo;
import co.yixiang.yshop.module.product.controller.app.product.vo.AppStoreProductRespVo;
import co.yixiang.yshop.module.product.dal.dataobject.storeproduct.StoreProductDO;
import co.yixiang.yshop.module.product.dal.dataobject.storeproductattrvalue.StoreProductAttrValueDO;
import co.yixiang.yshop.module.product.enums.product.ProductTypeEnum;
import co.yixiang.yshop.module.product.service.storeproduct.AppStoreProductService;
import co.yixiang.yshop.module.product.service.storeproductattrvalue.StoreProductAttrValueService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.STORE_STOCK_ERROR;
import static co.yixiang.yshop.module.product.enums.ErrorCodeConstants.STORE_PRODUCT_NOT_EXISTS;
import static co.yixiang.yshop.module.cart.enums.ErrorCodeConstants.STORE_CART_NOT_EXISTS;

/**
 * 购物车 Service 实现类
 *
 * @author yshop
 */
@Slf4j
@Service
@Validated
public class AppStoreCartServiceImpl extends ServiceImpl<StoreCartMapper,StoreCartDO> implements AppStoreCartService {

    @Resource
    private StoreCartMapper storeCartMapper;
    @Resource
    private ProductApi productApi;
    @Resource
    private AppStoreProductService appStoreProductService;
    @Resource
    private StoreProductAttrValueService storeProductAttrValueService;


    /**
     * 返回当前用户购物车总数量
     *
     * @param uid 用户id
     * @return int
     */
    @Override
    public int getUserCartNum(Long uid) {
        return storeCartMapper.cartSum(uid);
    }

    /**
     * 添加购物车
     * @param uid               用户id
     * @param productId         普通产品编号
     * @param cartNum           购物车数量
     * @param productAttrUnique 属性唯一值
     * @param isNew             1 加入购物车直接购买  0 加入购物车
     * @param combinationId     拼团id
     * @param seckillId         秒杀id
     * @param bargainId         砍价id
     * @return 购物车id
     */
    @Override
    public long addCart(Long uid, Long productId, Integer cartNum, String productAttrUnique,
                        Integer isNew, Long combinationId, Long seckillId, Long bargainId) {

        this.checkProductStock(uid, productId, cartNum, productAttrUnique);
        LambdaQueryWrapper<StoreCartDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreCartDO::getUid, uid)
                .eq(StoreCartDO::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue())
                .eq(StoreCartDO::getProductId, productId)
                .eq(StoreCartDO::getIsNew, isNew)
                .eq(StoreCartDO::getProductAttrUnique, productAttrUnique)
                .eq(StoreCartDO::getBargainId, bargainId)
                .eq(StoreCartDO::getCombinationId, combinationId)
                .eq(StoreCartDO::getSeckillId, seckillId)
                .orderByDesc(StoreCartDO::getId)
                .last("limit 1");

        StoreCartDO cart = storeCartMapper.selectOne(wrapper);

        StoreCartDO storeCart = StoreCartDO.builder()
                .cartNum(cartNum)
                .productAttrUnique(productAttrUnique)
                .productId(productId)
                .bargainId(bargainId)
                .combinationId(combinationId)
                .seckillId(seckillId)
                .isNew(isNew)
                .uid(uid)
                .build();
        if (cart != null) {
            if (CartTypeEnum.NEW_0.getValue().equals(isNew)) {
                storeCart.setCartNum(cartNum + cart.getCartNum());
            }
            storeCart.setId(cart.getId());
            storeCartMapper.updateById(storeCart);
        } else {
            storeCartMapper.insert(storeCart);
        }

        return storeCart.getId();
    }

    /**
     * 检测商品库存 库存加锁
     *
     * @param uid               用户ID
     * @param productId         产品ID
     * @param cartNum           购买数量
     * @param productAttrUnique 商品属性Unique
     */
    @Override
    public void checkProductStock(Long uid, Long productId, Integer cartNum, String productAttrUnique) {
        StoreProductDO product = appStoreProductService
                .lambdaQuery().eq(StoreProductDO::getId, productId)
                .eq(StoreProductDO::getIsShow, ShopCommonEnum.SHOW_1.getValue())
                .one();
        if (product == null) {
            throw exception(STORE_PRODUCT_NOT_EXISTS);
        }

        int stock = appStoreProductService.getProductStock(productId, productAttrUnique, "");
        if (stock < cartNum) {
            throw exception(new ErrorCode(1008003010, product.getStoreName() + "库存不足" + cartNum));
        }

    }


    /**
     * 购物车列表
     *
     * @param uid     用户id
     * @param cartIds 购物车id，多个逗号隔开
     * @param status  0-购购物车列表
     * @return map valid-有效购物车 invalid-失效购物车
     */
    @Override
    public Map<String, Object> getUserProductCartList(Long uid, String cartIds, Integer status) {
        LambdaQueryWrapper<StoreCartDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoreCartDO::getUid, uid)
                .eq(StoreCartDO::getIsPay, OrderInfoEnum.PAY_STATUS_0.getValue())
                .orderByDesc(StoreCartDO::getId);
        if (status == null) {
            wrapper.eq(StoreCartDO::getIsNew, CartTypeEnum.NEW_0.getValue());
        }
        if (StrUtil.isNotEmpty(cartIds)) {
            wrapper.in(StoreCartDO::getId, Arrays.asList(cartIds.split(",")));
        }
        List<StoreCartDO> carts = storeCartMapper.selectList(wrapper);

        List<AppStoreCartQueryVo> valid = new ArrayList<>();
        List<AppStoreCartQueryVo> invalid = new ArrayList<>();

        for (StoreCartDO storeCart : carts) {
            AppStoreProductRespVo storeProduct = appStoreProductService.getStoreProductById(storeCart.getProductId());
            AppStoreCartQueryVo storeCartQueryVo = StoreCartConvert.INSTANCE.convert01(storeCart);
            if (ObjectUtil.isNull(storeProduct)) {
                this.removeById(storeCart.getId());
            } else if (ShopCommonEnum.SHOW_0.getValue().equals(storeProduct.getIsShow()) || (storeProduct.getStock() == 0 && StrUtil.isEmpty(storeCart.getProductAttrUnique()))) {
                storeCartQueryVo.setProductInfo(storeProduct);
                invalid.add(storeCartQueryVo);
            } else {
                    StoreProductAttrValueDO productAttrValue = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValueDO>lambdaQuery()
                            .eq(StoreProductAttrValueDO::getUnique,storeCart.getProductAttrUnique()));
                    if (ObjectUtil.isNull(productAttrValue) || productAttrValue.getStock() == 0) {
                        storeCartQueryVo.setProductInfo(storeProduct);
                        invalid.add(storeCartQueryVo);
                    } else {
                        storeProduct.setAttrInfo(productAttrValue);
                        storeCartQueryVo.setProductInfo(storeProduct);
                        //普通商品金额
                        BigDecimal truePrice = storeProduct.getPrice();
                        //设置拼团价格
                        if(storeCart.getCombinationId() > 0 ){
                            truePrice = productAttrValue.getPinkPrice();
                        }
                        //设置秒杀价格
                        if( storeCart.getSeckillId() > 0){
                            truePrice = productAttrValue.getSeckillPrice();
                        }
                        storeCartQueryVo.setTruePrice(truePrice);
                        storeCartQueryVo.setTrueStock(productAttrValue.getStock());
                        valid.add(storeCartQueryVo);

                    }
                }

        }

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("valid", valid);
        map.put("invalid", invalid);
        return map;
    }

    /**
     * 改购物车数量
     *
     * @param cartId  购物车id
     * @param cartNum 数量
     * @param uid     uid
     */
    @Override
    public void changeUserCartNum(Long cartId, int cartNum, Long uid) {
        StoreCartDO cart = this.lambdaQuery()
                .eq(StoreCartDO::getUid, uid)
                .eq(StoreCartDO::getId, cartId)
                .one();
        if (cart == null) {
            throw exception(STORE_CART_NOT_EXISTS);
        }

        if (cartNum <= 0) {
            throw exception(STORE_STOCK_ERROR);
        }

        //普通商品库存
        int stock = appStoreProductService.getProductStock(cart.getProductId()
                , cart.getProductAttrUnique(), "");
        if (stock < cartNum) {
            throw exception(new ErrorCode(1008006002, "该产品库存不足" + cartNum));
        }

        if (cartNum == cart.getCartNum()) {
            return;
        }

        StoreCartDO storeCart = new StoreCartDO();
        storeCart.setCartNum(cartNum);
        storeCart.setId(cartId);

        storeCartMapper.updateById(storeCart);


    }


    /**
     * 删除购物车
     *
     * @param uid uid
     * @param ids 购物车id集合
     */
    @Override
    public void removeUserCart(Long uid, List<String> ids) {
        List<Long> newids = ids.stream().map(Long::new).collect(Collectors.toList());
        storeCartMapper.delete(Wrappers.<StoreCartDO>lambdaQuery()
                .eq(StoreCartDO::getUid, uid)
                .in(StoreCartDO::getId, newids));
    }

    /**
     * 修改购物车支付状态
     * @param cartIds
     */
    @Async
    @Override
    //@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateCartPayStatus(List<String> cartIds) {
        log.info("==========修改购物车支付状态start===========");
        StoreCartDO cartObj = new StoreCartDO();
        cartObj.setIsPay(OrderInfoEnum.PAY_STATUS_1.getValue());
        storeCartMapper.update(cartObj, Wrappers.<StoreCartDO>lambdaQuery()
                .in(StoreCartDO::getId, cartIds));
    }



}
