package cn.ysk.cashier.mybatis.service.impl;

import cn.ysk.cashier.mybatis.entity.Activate;
import cn.ysk.cashier.mybatis.entity.TbActivateProduct;
import cn.ysk.cashier.mybatis.mapper.*;
import cn.ysk.cashier.mybatis.service.TbActivateProductService;
import cn.ysk.cashier.mybatis.vo.ActivateProsVo;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductSku;
import cn.ysk.cashier.pojo.shop.TbMerchantAccount;
import cn.ysk.cashier.repository.product.TbProductRepository;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.ysk.cashier.exception.NewBadRequestException;
import cn.ysk.cashier.mybatis.entity.StorageVo;
import cn.ysk.cashier.mybatis.entity.TbUserStorage;
import cn.ysk.cashier.mybatis.service.ShopService;
import cn.ysk.cashier.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

/**
 * @author admin
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-10-30
 **/
@Service
public class ShopServiceImpl implements ShopService {

    @Autowired
    private TbUserStorageMapper userStorageMapper;
    @Autowired
    private TbMerchantAccountMapper tbMerchantAccountMapper;
    @Autowired
    private TbProducSkutMapper producSkutMapper;
    @Autowired
    private ActivateMapper activateMapper;
    @Autowired
    private TbProductRepository tbProductRepository;
    @Resource
    private TbActivateProductService actProductService;
    @Override
    public Object findStorage(Integer shopId, String account, Pageable pageable) {
        QueryWrapper<TbUserStorage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id", shopId);
        if (StringUtils.isNotEmpty(account)) {
            queryWrapper.eq("account", account);
        }
        IPage<TbUserStorage> iPage = userStorageMapper.selectPage(new Page<>(pageable.getPageNumber(), pageable.getPageSize()), queryWrapper);
        return PageUtil.toPage(iPage.getRecords(), iPage.getTotal());
    }

    @Override
    public void outStorage(Integer id, String userName, Integer num) {
        if (Objects.isNull(num) || num < 0) {
            throw new NewBadRequestException("请输入出库数量");
        }
        QueryWrapper<TbMerchantAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("account", userName);
        TbMerchantAccount merchantAccount = tbMerchantAccountMapper.selectOne(wrapper);

        QueryWrapper<TbUserStorage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        queryWrapper.eq("shop_id", merchantAccount.getShopId());
        TbUserStorage userStorage = userStorageMapper.selectOne(queryWrapper);
        if (Objects.isNull(userStorage)) {
            throw new NewBadRequestException("存储商品在该店铺不存在");
        }
        if (userStorage.getNum() < num) {
            throw new NewBadRequestException("库存不足");
        }
        userStorage.setNum(userStorage.getNum() - num);
        userStorage.setOutNum(userStorage.getOutNum() + num);
        userStorageMapper.updateById(userStorage);
    }

    @Override
    public void inStorage(StorageVo storageVo, String userName) {
        if (Objects.isNull(storageVo.getNum()) || storageVo.getNum() < 0) {
            throw new NewBadRequestException("请输入出库数量");
        }
        QueryWrapper<TbMerchantAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("account", userName);
        TbMerchantAccount merchantAccount = tbMerchantAccountMapper.selectOne(wrapper);

        QueryWrapper<TbUserStorage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_name", storageVo.getProductName());
        queryWrapper.eq("account", storageVo.getAccount());
        queryWrapper.eq("shop_id", merchantAccount.getShopId());
        TbUserStorage userStorage = userStorageMapper.selectOne(queryWrapper);
        if (Objects.nonNull(userStorage)) {
            userStorage.setNum(userStorage.getNum() + storageVo.getNum());
            userStorage.setInNum(userStorage.getInNum() + storageVo.getNum());
            userStorageMapper.updateById(userStorage);
        }else {
            userStorage = new TbUserStorage();
            userStorage.setAccount(storageVo.getAccount());
            userStorage.setCreateTime(new Date());
            userStorage.setShopId(merchantAccount.getShopId());
            userStorage.setNum(storageVo.getNum());
            userStorage.setOutNum(0);
            userStorage.setInNum(storageVo.getNum());
            userStorage.setImgUrl(storageVo.getImg());
            userStorage.setProductName(storageVo.getImg());
            userStorage.setUnit(storageVo.getUnit());
            userStorageMapper.insert(userStorage);
        }
    }

    @Override
    public Object findActivate(String shopId) {
        QueryWrapper<Activate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopId);
        queryWrapper.orderByDesc("id");
        List<Activate> list = activateMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public void modityActivate(Activate activate) {
        if (Objects.nonNull(activate.getId()) && activate.getId() > 0){
            activate.setHandselType("GD");
            activate.setMaxNum(activate.getMinNum());
            activateMapper.updateById(activate);
        }else {
            activate.setHandselType("GD");
            activate.setMaxNum(activate.getMinNum());
            activateMapper.insert(activate);
        }
        if(!CollectionUtils.isEmpty(activate.getProducts())){
            List<Integer> collect = new ArrayList<>();
            for (TbActivateProduct product : activate.getProducts()) {
                product.setActivateId(activate.getId());
                if (product.getId() != null) collect.add(product.getId());
            }
            QueryWrapper<TbActivateProduct> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("activate_id",activate.getId());
            List<TbActivateProduct> actProducts = actProductService.list(queryWrapper);
            for (TbActivateProduct actProduct : actProducts) {
                if (!collect.contains(actProduct.getId())) {
                    actProductService.removeById(actProduct.getId());
                }
            }
            actProductService.saveOrUpdateBatch(activate.getProducts());
        }else {
            LambdaQueryWrapper<TbActivateProduct> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TbActivateProduct::getActivateId, activate.getId()); // 条件：年龄等于30
            actProductService.remove(queryWrapper);
        }
    }

    @Override
    public List<ActivateProsVo> findActivatePros(Integer activateId) {
        QueryWrapper<TbActivateProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activate_id", activateId);
        List<TbActivateProduct> actProducts = actProductService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(actProducts)) {
            Map<Integer, Integer> map = actProducts.stream().collect(
                    Collectors.toMap(
                            TbActivateProduct::getProductId,
                            TbActivateProduct::getNum,
                            (existing, replacement) -> existing));
            if (!CollectionUtils.isEmpty(map)) {
                List<TbProduct> products = tbProductRepository.findByIds(new ArrayList<>(map.keySet()));
                List<ActivateProsVo> results= new ArrayList<>();
                for (TbProduct product : products) {
                    ActivateProsVo pro =new ActivateProsVo(product.getId(),product.getName(),product.getCoverImg());
                    pro.setNum(map.get(pro.getId()));
                    results.add(pro);
                }
                return results;
            }
        }
        return new ArrayList<>();
    }
}