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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.StrUtil;
import cn.ysk.cashier.dto.TbPlatformDictDto;
import cn.ysk.cashier.dto.product.TbProductDto;
import cn.ysk.cashier.dto.product.TbProductQueryCriteria;
import cn.ysk.cashier.dto.product.TbProductSortCriteria;
import cn.ysk.cashier.dto.shop.TbCouponCategoryDto;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mapper.product.TbProductMapper;
import cn.ysk.cashier.mapper.product.TbProductSkuMapper;
import cn.ysk.cashier.mybatis.entity.TagProductDepts;
import cn.ysk.cashier.mybatis.mapper.TbProducSkutMapper;
import cn.ysk.cashier.mybatis.service.TagProductDeptsService;
import cn.ysk.cashier.pojo.product.*;
import cn.ysk.cashier.pojo.shop.TbPurchaseNotice;
import cn.ysk.cashier.pojo.shop.TbShopUnit;
import cn.ysk.cashier.repository.product.*;
import cn.ysk.cashier.repository.shop.TbPurchaseNoticeRepository;
import cn.ysk.cashier.repository.shop.TbShopUnitRepository;
import cn.ysk.cashier.repository.shop.TbShopUserDutyDetailRepository;
import cn.ysk.cashier.service.TbPlatformDictService;
import cn.ysk.cashier.service.product.TbProductService;
import cn.ysk.cashier.service.shop.TbCouponCategoryService;
import cn.ysk.cashier.utils.*;
import cn.ysk.cashier.vo.TbProductVo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.DoubleSupplier;
import java.util.stream.Collectors;

/**
 * @author lyf
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-12-11
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class TbProductServiceImpl implements TbProductService {

    private final TbProductRepository tbProductRepository;
    private final TbProductMapper tbProductMapper;
    private final TbProductSkuRepository tbProductSkuRepository;
    private final TbShopUnitRepository tbShopUnitRepository;
    private final TbProductSpecRepository tbProductSpecRepository;
    private final TbProductSkuMapper TbProductSkuMapper;
    private final TbProductSkuResultRepository tbProductSkuResultRepository;
    private final TbShopCategoryRepository tbShopCategoryRepository;
    private final TbShopUserDutyDetailRepository tbShopUserDutyDetailRe;
    private final TbCouponCategoryService tbCouponCategoryService;
    private final TbPlatformDictService tbPlatformDictService;
    private final TagProductDeptsService tagProductService;
    private final TbPurchaseNoticeRepository noticeRepository;
    private final TbProducSkutMapper producSkutMapper;
    private final cn.ysk.cashier.mybatis.mapper.TbProductMapper productMapper;
    private final TbProductSkuResultRepository productSkuResultRepository;


    private final RedisUtils redisUtils;


    public static String setType(String type) {
        switch (type) {
            case "normal":
                return "单规格";
            case "sku":
                return "多规格";
            case "weight":
                return "称重商品";
            case "currentPrice":
                return "时价商品";
            case "group":
                return "套餐商品/团购卷";
            default:
                return type;
        }
    }

    @Override
    public Map<String, Object> queryAll(TbProductQueryCriteria criteria, boolean isAdmin) {
        Sort sort = Sort.by(Sort.Direction.ASC, "sort");
        Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
        //查询商品数据
        Page<TbProduct> page = tbProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        List<String> productId = new ArrayList<>();
        List<Integer> unitId = new ArrayList<>();
        List<Integer> specId = new ArrayList<>();
        List<String> categoryId = new ArrayList<>();
        List<Integer> productIdInt = new ArrayList<>();
        for (TbProduct product : page.getContent()) {
            //记录商品id
            productId.add(product.getId().toString());
            productIdInt.add(product.getId());
            //记录单位id
            if (product.getUnitId() != null) {
                if (!"".equals(product.getUnitId())) {
                    unitId.add(product.getUnitId());
                }
            }
            //记录规格id
            specId.add(product.getSpecId());
            //记录分类id
            categoryId.add(product.getCategoryId());
        }

        //单位
        List<TbShopUnit> tbShopUnits = new ArrayList<>();
        if (!unitId.isEmpty()) {
            tbShopUnits = tbShopUnitRepository.searchUnit(unitId);
        }
        //商品规格
        List<TbProductSpec> tbProductSpecs = new ArrayList<>();
        if (!specId.isEmpty()) {
            tbProductSpecs = tbProductSpecRepository.searchSpec(specId);
        }
        //分类
        List<TbShopCategory> tbShopCategory = new ArrayList<>();
        if (!categoryId.isEmpty()) {
            List<Integer> categoryIdInt = ListUtil.stringChangeIntegerList(categoryId);
            tbShopCategory = tbShopCategoryRepository.searchCategory(categoryIdInt);
        }
        //销量
        List<Object[]> objects = new ArrayList<>();
        if (!productIdInt.isEmpty()) {
            objects = tbShopUserDutyDetailRe.searchUUserDutyDetail(productIdInt);
        }
        //组装
        List<TbProductVo> tbProductVoList = new ArrayList<>();
        for (TbProduct product : page.getContent()) {
            //sku
            List<TbProductSku> tbProductSkus = tbProductSkuRepository.searchSku(product.getId().toString());

           BigDecimal maxPrice=tbProductSkus.stream().map(TbProductSku::getSalePrice).max(BigDecimal::compareTo).get();
           log.info("maxPrice:{}",maxPrice);

            List<TbProductSku> skuList = new ArrayList<>();
            TbProductVo tbProductVo = new TbProductVo();
            //sku,并且计算销量以及库存
            double stockNumber = 0.00;

            tbProductVo.setMaxPrice(maxPrice);

            if (product.getIsDistribute() == 1) {
                stockNumber = product.getStockNumber() == null ? 0 : product.getStockNumber();
                TbProductSku tbProductSku = null;
                if (isAdmin) {
                    if (!tbProductSkus.isEmpty()) {
                        tbProductSku = BeanUtil.copyProperties(tbProductSkus.get(0), TbProductSku.class);
                        tbProductSku.setStockNumber(stockNumber);
                    }
                    skuList.add(tbProductSku);
                }
            } else {
                for (TbProductSku sku : tbProductSkus) {
                    //sku
                    if (sku.getProductId().equals(product.getId().toString())) {
                        skuList.add(sku);
                        stockNumber = isAdmin ? sku.getStockNumber() : stockNumber + sku.getStockNumber();
                    }
                }
            }
            tbProductVo.setStockNumber(stockNumber);
            tbProductVo.setSkuList(skuList);
            //单位
            if (tbShopUnits.isEmpty()) {
                tbProductVo.setUnitName("");
            } else {
                for (TbShopUnit tbShopUnit : tbShopUnits) {
                    if (tbShopUnit.getId().equals(product.getUnitId())) {
                        tbProductVo.setUnitName(tbShopUnit.getName());
                    }
                }
            }
            //商品规格
            if (tbProductSpecs.isEmpty()) {
                tbProductVo.setSpecsInfo(new HashMap<>());
            } else {
                for (TbProductSpec spec : tbProductSpecs) {
                    if (spec.getId().equals(product.getSpecId())) {
                        HashMap<String, String> specsMap = new HashMap<>();
                        specsMap.put(spec.getName(), spec.getSpecList());
                        tbProductVo.setSpecsInfo(specsMap);
                    }
                }
            }
            //分类
            if (tbShopCategory.isEmpty()) {
                tbProductVo.setCategoryName("");
            } else {
                for (TbShopCategory shopCategory : tbShopCategory) {
                    if (shopCategory.getId().toString().equals(product.getCategoryId())) {
                        tbProductVo.setCategoryName(shopCategory.getName());
                    }
                }
            }
            //销量
            if (objects.isEmpty()) {
                tbProductVo.setRealSalesNumber(0.00);
            } else {
                for (Object[] o : objects) {
                    if (((Integer) o[1]).equals(product.getId())) {
                        BigDecimal bigDecimal = (BigDecimal) o[0];
                        tbProductVo.setRealSalesNumber(bigDecimal.doubleValue());
                    }
                }
            }
            BeanUtils.copyProperties(product, tbProductVo);
            tbProductVo.setTypeEnum(setType(tbProductVo.getTypeEnum()));
            tbProductVoList.add(tbProductVo);
        }
        return PageUtil.toPage(tbProductVoList, page.getTotalElements());
    }


    @Override
    public TbProductVo findByProductId(Integer id) throws Exception {
        TbProduct tbProduct = tbProductRepository.findById(id).orElseGet(TbProduct::new);

        //单位
//        CompletableFuture<TbShopUnit> tbShopUnits = CompletableFuture.supplyAsync(() ->
//                tbShopUnitRepository.searchUnit(Integer.valueOf(StringUtils.isEmpty(tbProduct.getUnitId()) ? null : tbProduct.getUnitId())));
        //sku
        CompletableFuture<List<TbProductSku>> tbProductSkus = CompletableFuture.supplyAsync(() ->
                tbProductSkuRepository.searchSku(tbProduct.getId().toString()));
        //商品规格
        CompletableFuture<TbProductSpec> tbProductSpec = CompletableFuture.supplyAsync(() ->
                tbProductSpecRepository.searchSpec(tbProduct.getSpecId()));

//        Threads.call(tbShopUnits, tbProductSkus, tbProductSpec);
        Threads.call(tbProductSkus, tbProductSpec);
        //组装
        TbProductVo tbProductVo = new TbProductVo();
        tbProductVo.setStockNumber(tbProduct.getStockNumber() == null ? 0.00 : tbProduct.getStockNumber());
        tbProductVo.setCategoryId(StringUtils.isNotBlank(tbProduct.getCategoryId())?Integer.valueOf(tbProduct.getCategoryId()):null);
        //单位
//        if (tbProduct.getUnitId() == null) {
//            tbProductVo.setUnitId(null);
//            tbProductVo.setUnitName(null);
//        }
        //套餐
        if (tbProduct.getGroupSnap() == null) {
            tbProductVo.setGroupSnap(new JSONArray());
        } else {
            tbProductVo.setGroupSnap(ListUtil.stringChangeList(tbProduct.getGroupSnap()));
        }
        BeanUtils.copyProperties(tbProduct, tbProductVo);
        if (!org.apache.commons.lang3.StringUtils.isBlank(tbProduct.getImages())) {
            tbProductVo.setImages(ListUtil.stringChangeList(tbProduct.getImages()));
        } else {
            tbProductVo.setImages(new JSONArray());
        }
        HashMap<String, String> map = new HashMap<>();
        //商品规格
        if (tbProductSpec.get() == null) {
            tbProductVo.setSpecsInfo(map);
        } else {
            map.put(tbProductSpec.get().getName(), tbProductSpec.get().getSpecList());
            tbProductVo.setSpecsInfo(map);
        }
        //sku
        if (tbProductSkus.get() == null) {
            tbProductVo.setSkuList(new ArrayList<>());
        } else {
            tbProductVo.setSkuList(tbProductSkus.get());
        }
        if ("sku".equals(tbProductVo.getTypeEnum())) {
            Optional<TbProductSkuResult> skuResult = tbProductSkuResultRepository.findById(tbProductVo.getId());
            tbProductVo.setSkuSnap(skuResult.get().getTagSnap());
        }
        if ("group".equals(tbProductVo.getTypeEnum())) {
            if (StringUtils.isNotBlank(tbProduct.getGroupCategoryId())) {
                JSONArray objects = ListUtil.stringChangeList(tbProduct.getGroupCategoryId());
                for (Object groupCategoryId : objects) {
                    TbCouponCategoryDto byId = tbCouponCategoryService.findById(Integer.valueOf(groupCategoryId.toString()));
                    tbProductVo.getGroupCategoryId().add(byId);
                }
            }
            List<TagProductDepts> tagProductDepts = tagProductService.queryAllByProductId(tbProductVo.getId());
            if (!CollectionUtils.isEmpty(tagProductDepts)) {
                List<Integer> collect = tagProductDepts.stream().map(TagProductDepts::getTagId).collect(Collectors.toList());
                List<TbPlatformDictDto> tags = tbPlatformDictService.queryByIds(collect);
                tbProductVo.setTags(tags);
            }
            TbPurchaseNotice notice = noticeRepository.findByCouponId(id);
            if (notice != null) {
                tbProductVo.setNotices(notice);
            }
        }
        return tbProductVo;
    }

    @Override
    public List<TbProduct> findByProductList(List<String> productList) {
        List<Integer> productListInt = productList.stream()
                .map(Integer::parseInt)
                .collect(Collectors.toList());
        List<TbProduct> byIds = tbProductRepository.findByIds(productListInt);

        return byIds;
    }

    @Override
    public List<TbProductDto> queryAlls(TbProductQueryCriteria criteria) {
        return tbProductMapper.toDto(tbProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public TbProductDto findById(Integer id) {
        TbProduct tbProduct = tbProductRepository.findById(id).orElseGet(TbProduct::new);
        ValidationUtil.isNull(tbProduct.getId(), "TbProduct", "id", id);
        return tbProductMapper.toDto(tbProduct);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object create(TbProductVo resources) {
        TbProduct product = new TbProduct();
        //组装
        BeanUtil.copyProperties(resources, product, CopyOptions.create().setIgnoreNullValue(true));
        if(CollectionUtils.isEmpty(resources.getSkuList())){
            throw new BadRequestException("商品规格不可为空");
        }
        if (!"group".equals(resources.getTypeEnum())) {
            if (resources.getCategoryId() == null) {
                throw new BadRequestException("必填内容未填写");
            }
//            if (resources.getIsShowMall() == 1) {
//                for (TbProductSku sku : resources.getSkuList()) {
//                    if (sku.getStockNumber() <= 0) {
//                        throw new BadRequestException("上架区域包括小程序时,库存数量必须大于0。");
//                    }
//                }
//            }
            product.setCategoryId(String.valueOf(resources.getCategoryId()));
        }
        if (product.getUnitId() == null) {
            throw new BadRequestException("商品单位未填写");
        }
        if (!CollectionUtils.isEmpty(resources.getImages())) {
            product.setImages(resources.getImages().toString());
        }
        product.setIsDel(0);
        product.setIsDelete(0);
        product.setIsFreeFreight(1);
        product.setStatus(1);
        product.setCreatedAt(Instant.now().toEpochMilli());
        product.setUpdatedAt(Instant.now().toEpochMilli());
        if ("sku".equals(resources.getTypeEnum())) {
            List<BigDecimal> collect = resources.getSkuList().stream().map(TbProductSku::getSalePrice).sorted().collect(Collectors.toList());
            product.setLowPrice(collect.get(0));
        }
        if ("group".equals(resources.getTypeEnum())) {
            //套餐内容
            if (!resources.getGroupSnap().isEmpty()) {
                product.setGroupSnap(ListUtil.JSONArrayChangeString(resources.getGroupSnap()));
                product.setIsCombo(1);
            }
            if (!CollectionUtils.isEmpty(resources.getGroupCategoryId())) {
                List<Integer> collect = resources.getGroupCategoryId().stream().map(TbCouponCategoryDto::getId).collect(Collectors.toList());
                product.setGroupCategoryId(collect.toString());
            }
            if (!CollectionUtils.isEmpty(resources.getTags())) {
                for (TbPlatformDictDto tag : resources.getTags()) {
                    tagProductService.setTag(tag.getId(), resources.getId());
                }
            }
        }

        TbProduct save = tbProductRepository.save(product);
        if (save.getId() == null) {
            throw new BadRequestException("添加商品失败");
        }
        save.setSort(save.getId());
        tbProductRepository.save(save);
        //sku
        if (resources.getSkuList() != null) {
            Integer warnLine = 0;
            List<TbProduct> productList = tbProductRepository.selectByShopId(resources.getShopId());
            if (!productList.isEmpty()) {
                TbProduct p = productList.get(0);
                List<TbProductSku> productSkus = tbProductSkuRepository.searchSku(p.getId().toString());
                if (!productSkus.isEmpty()) {
                    warnLine = productSkus.get(0).getWarnLine();
                }
            }

            List<TbProductSku> skuList = new ArrayList<>();
            for (TbProductSku sku : resources.getSkuList()) {
                sku.setProductId(String.valueOf(save.getId()));
                sku.setShopId(save.getShopId());
                sku.setCreatedAt(Instant.now().toEpochMilli());
                sku.setUpdatedAt(Instant.now().toEpochMilli());
                sku.setIsGrounding(1);
                sku.setWarnLine(warnLine);
                skuList.add(sku);
            }
            List<TbProductSku> tbProductSkus = tbProductSkuRepository.saveAll(skuList);
            Map<Integer, Double> idStockMap = tbProductSkus.stream()
                    .collect(Collectors.toMap(TbProductSku::getId, TbProductSku::getStockNumber));
            redisUtils.redisUp(1, save.getShopId(), idStockMap);
        }
        //保存到sku_result
        if ("sku".equals(resources.getTypeEnum())) {
            TbProductSkuResult productSkuResult = new TbProductSkuResult();
            productSkuResult.setCreatedAt(Instant.now().toEpochMilli());
            productSkuResult.setUpdatedAt(Instant.now().toEpochMilli());
            productSkuResult.setTagSnap(resources.getSkuSnap());
            productSkuResult.setId(save.getId());
            tbProductSkuResultRepository.save(productSkuResult);
        } else if ("group".equals(resources.getTypeEnum())) {
            TbPurchaseNotice notices = resources.getNotices();
            if (StringUtils.isBlank(notices.getDateUsed())
                    && StringUtils.isBlank(notices.getAvailableTime())
                    && StringUtils.isBlank(notices.getBookingType())
                    && StringUtils.isBlank(notices.getRefundPolicy())) {
                throw new BadRequestException("添加购买须知失败，必填项未填写");
            }
            resources.getNotices().setCouponId(save.getId());
            noticeRepository.save(resources.getNotices());
        }
        return resources;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TbProductVo resources) {
        TbProduct product = new TbProduct();
        //组装
        BeanUtils.copyProperties(resources, product);
        if(CollectionUtils.isEmpty(resources.getSkuList())){
            throw new BadRequestException("规格内容不可为空");
        } else if (!"sku".equals(product.getTypeEnum())) {
            product.setSelectSpec("[]");
            product.setSpecTableHeaders("[]");
            if (resources.getSkuList().size() > 1) {
                throw new BadRequestException("规格数据异常");
            }
        }
        if (!"group".equals(product.getTypeEnum())) {
            if (resources.getCategoryId() == null) throw new BadRequestException("商品分类不可为空");
            product.setIsCombo(0);
            product.setGroupSnap(null);
            if (resources.getNotices() != null && resources.getNotices().getId() != null) {
                noticeRepository.deleteById(resources.getNotices().getId());
            }
        }
        product.setIsDel(0);
        product.setIsDelete(0);
        product.setIsFreeFreight(1);
        product.setStatus(1);
        product.setUpdatedAt(Instant.now().toEpochMilli());
        product.setImages(resources.getImages().toString());
        product.setStockNumber(resources.getStockNumber().intValue());
        if ("sku".equals(resources.getTypeEnum())) {
            List<BigDecimal> collect = resources.getSkuList().stream().map(TbProductSku::getSalePrice).sorted().collect(Collectors.toList());
            product.setLowPrice(collect.get(0));
        }
        if ("group".equals(resources.getTypeEnum())) {
            //套餐内容
            if (!resources.getGroupSnap().isEmpty()) {
                product.setGroupSnap(ListUtil.JSONArrayChangeString(resources.getGroupSnap()));
                product.setIsCombo(1);
            }
            if (!CollectionUtils.isEmpty(resources.getGroupCategoryId())) {
                List<Integer> collect = resources.getGroupCategoryId().stream().map(TbCouponCategoryDto::getId).collect(Collectors.toList());
                product.setGroupCategoryId(collect.toString());
            }
            if (!CollectionUtils.isEmpty(resources.getTags())) {
                for (TbPlatformDictDto tag : resources.getTags()) {
                    tagProductService.setTag(tag.getId(), resources.getId());
                }
            }
            noticeRepository.save(resources.getNotices());

        }else {
            product.setCategoryId(resources.getCategoryId().toString());
        }
        TbProduct save = tbProductRepository.save(product);

        //sku
        if (resources.getSkuList() != null) {
//            if ("sku".equals(save.getTypeEnum())) {
                List<Integer> collect = resources.getSkuList().stream().map(TbProductSku::getId).collect(Collectors.toList());
                List<TbProductSku> tbProductSkus = tbProductSkuRepository.searchSku(resources.getId().toString());
                for (TbProductSku productSkus : tbProductSkus) {
                    if (!collect.contains(productSkus.getId())) {
                        tbProductSkuRepository.deleteBySkuId(productSkus.getId());
                    }
                }
//            }
            tbProductSkuRepository.saveAll(resources.getSkuList());
        }
        //保存到sku_result
        if ("sku".equals(resources.getTypeEnum())) {
            TbProductSkuResult productSkuResult = new TbProductSkuResult();
            productSkuResult.setCreatedAt(Instant.now().toEpochMilli());
            productSkuResult.setUpdatedAt(Instant.now().toEpochMilli());
            productSkuResult.setTagSnap(resources.getSkuSnap());
            productSkuResult.setId(save.getId());
            tbProductSkuResultRepository.save(productSkuResult);
        }else {
            tbProductSkuResultRepository.deleteByIdN(save.getId());
            if ("group".equals(resources.getTypeEnum())) {
                TbPurchaseNotice notices = resources.getNotices();
                if (StringUtils.isBlank(notices.getDateUsed())
                        && StringUtils.isBlank(notices.getAvailableTime())
                        && StringUtils.isBlank(notices.getBookingType())
                        && StringUtils.isBlank(notices.getRefundPolicy())) {
                    throw new BadRequestException("修改购买须知失败，必填项未填写");
                }
                resources.getNotices().setCouponId(save.getId());
                noticeRepository.save(resources.getNotices());
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateIsHot(Integer id,Integer isHot) {
        tbProductRepository.updateIsHot(id,isHot);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateIsStock(Integer proId, String shopId,Integer isStock) {
        tbProductRepository.updateIsStock(proId,shopId,isStock);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void upProSort(TbProductSortCriteria param) {
        Integer strSort = tbProductRepository.findById(param.getStrId()).get().getSort();
        Integer endSort = tbProductRepository.findById(param.getEndId()).get().getSort();
        List<TbProduct> list = tbProductRepository.findByIds(param.getIds());
        Integer sort = 0;
        Integer strIndex = -1;
        if(strSort<endSort){
            for (int i = list.size() - 1; i >= 0; i--) {
                TbProduct product = list.get(i);
                if(product.getId().equals(param.getEndId())) {
                    sort=product.getSort();
                    strIndex=i;
                }
                if(!strIndex.equals(-1)){
                    if (product.getId().equals(param.getStrId())){
                        product.setSort(sort);
                        tbProductRepository.save(product);
                        break;
                    }
                    TbProduct product1 = list.get(i - 1);
                    product.setSort(product1.getSort());
                    tbProductRepository.save(product);
                }
            }
        }else {
            for (int i = 0; i < list.size(); i++) {
                TbProduct product = list.get(i);
                if(product.getId().equals(param.getEndId())) {
                    sort=product.getSort();
                    strIndex=i;
                }
                if(!strIndex.equals(-1)){
                    if (product.getId().equals(param.getStrId())){
                        product.setSort(sort);
                        tbProductRepository.save(product);
                        break;
                    }
                    Integer nextIndex= i + 1;
                    TbProduct product1 = list.get(nextIndex);
                    product.setSort(product1.getSort());
                    tbProductRepository.save(product);
                }
            }
        }
    }

    @Override
    public void updateStockNumber(Integer id, Double stockNumber) {
        tbProductRepository.updateProductStockNumber(id, stockNumber.intValue());
    }

    @Override
    @Transactional
    public void deleteAll(Integer[] ids) {
        List<Integer> list = Arrays.asList(ids);
        tbProductRepository.updateByStatus(list);
        list.forEach(productId -> {
            List<TbProductSku> tbProductSkus = tbProductSkuRepository.searchSku(productId.toString());
            Map<Integer, Double> idStockMap = tbProductSkus.stream()
                    .collect(Collectors.toMap(TbProductSku::getId, TbProductSku::getStockNumber));
            redisUtils.redisUp(2, tbProductSkus.get(0).getShopId(), idStockMap);
        });
    }

    @Override
    public void download(List<TbProductDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbProductDto tbProduct : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("商品来源 NORMAL普通商品 --,SCORE积分商品", tbProduct.getSourcePath());
            map.put("商户Id", tbProduct.getMerchantId());
            map.put("店铺id", tbProduct.getShopId());
            map.put("商品名称", tbProduct.getName());
            map.put("商品类型（属性）:REAL- 实物商品 VIR---虚拟商品", tbProduct.getType());
            map.put("包装费", tbProduct.getPackFee());
            map.put("商品最低价", tbProduct.getLowPrice());
            map.put("单位Id", tbProduct.getUnitId());
            map.put("商品封面图", tbProduct.getCoverImg());
            map.put(" categoryId", tbProduct.getCategoryId());
            map.put("商品规格", tbProduct.getSpecId());
            map.put("品牌Id", tbProduct.getBrandId());
            map.put("短标题--促销语", tbProduct.getShortTitle());
            map.put(" lowMemberPrice", tbProduct.getLowMemberPrice());
            map.put("单位镜像", tbProduct.getUnitSnap());
            map.put("商品分享图", tbProduct.getShareImg());
            map.put("商品图片（第一张为缩略图，其他为详情）", tbProduct.getImages());
            map.put("商品视频URL地址", tbProduct.getVideo());
            map.put("视频封面图", tbProduct.getVideoCoverImg());
            map.put("排序", tbProduct.getSort());
            map.put("0-不限购", tbProduct.getLimitNumber());
            map.put("商品赚送积分", tbProduct.getProductScore());
            map.put("0--待审核 1审核通过 -1审核失败  -2违规下架", tbProduct.getStatus());
            map.put("审核失败原因", tbProduct.getFailMsg());
            map.put("是否推荐,店铺推荐展示", tbProduct.getIsRecommend());
            map.put("是否热销", tbProduct.getIsHot());
            map.put("是否新品", tbProduct.getIsNew());
            map.put("是否促销1-是0-否", tbProduct.getIsOnSale());
            map.put("是否展示0-下架 1上架---废弃", tbProduct.getIsShow());
            map.put("商品规格：0-单规格 1多规格", tbProduct.getTypeEnum());
            map.put("是否独立分销", tbProduct.getIsDistribute());
            map.put("是否回收站 0-否，1回收站", tbProduct.getIsDel());
            map.put("是否开启库存", tbProduct.getIsStock());
            map.put("是否暂停销售", tbProduct.getIsPauseSale());
            map.put("是否免邮1-是 0-否", tbProduct.getIsFreeFreight());
            map.put("邮费模版", tbProduct.getFreightId());
            map.put("商品当前生效策略", tbProduct.getStrategyType());
            map.put("策略Id", tbProduct.getStrategyId());
            map.put("vip专属", tbProduct.getIsVip());
            map.put("是否删除", tbProduct.getIsDelete());
            map.put("购买须知", tbProduct.getNotice());
            map.put(" createdAt", tbProduct.getCreatedAt());
            map.put(" updatedAt", tbProduct.getUpdatedAt());
            map.put("基础出售数量", tbProduct.getBaseSalesNumber());
            map.put("实际销量", tbProduct.getRealSalesNumber());
            map.put("合计销量", tbProduct.getSalesNumber());
            map.put("点赞次数", tbProduct.getThumbCount());
            map.put("收藏次数", tbProduct.getStoreCount());
            map.put("支持堂食", tbProduct.getFurnishMeal());
            map.put("支持配送", tbProduct.getFurnishExpress());
            map.put("支持自提", tbProduct.getFurnishDraw());
            map.put("支持虚拟", tbProduct.getFurnishVir());
            map.put("是否套餐", tbProduct.getIsCombo());
            map.put("套餐内容", tbProduct.getGroupSnap());
            map.put(" isShowCash", tbProduct.getIsShowCash());
            map.put(" isShowMall", tbProduct.getIsShowMall());
            map.put("是否需要审核", tbProduct.getIsNeedExamine());
            map.put("线上商城展示状态0待审核 -1 异常 1正常", tbProduct.getShowOnMallStatus());
            map.put("提交审核时间", tbProduct.getShowOnMallTime());
            map.put("线上商城展示失败原因", tbProduct.getShowOnMallErrorMsg());
            map.put("使用标签打印 选择 是 并在 前台>本机设置 勾选打印标签后，收银完成后会自动打印对应数量的标签数", tbProduct.getEnableLabel());
            map.put("税率", tbProduct.getTaxConfigId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void incrStockNumber(String productId, Integer number) {
        tbProductRepository.incrProductStockNumber(Integer.valueOf(productId), number);
    }

    @Override
    public void returnStockByPro(Integer productId, Integer productSkuId, Integer num) {
        log.info("开始返还库存，订单超时取消，商品id：{}", productId);
        TbProduct product = tbProductRepository.findById(productId).orElse(null);
        if (product == null) {
            log.info("返还库存失败，商品不存在： {}", productId);
            return;
        }
        if (product.getIsDistribute() == 1) {
            tbProductRepository.incrStock(productId, num);
        }else {
            tbProductSkuRepository.incrStock(productSkuId, Double.valueOf(num));
        }
    }

    @Override
    public Object activateProduct(Integer page, Integer size, Integer categoryId, Integer shopId, Integer productId) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<TbProduct> page1 = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, size);
        QueryWrapper<TbProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", 0)
                .eq("shop_id", shopId)
                .eq("is_delete", 0)
                .eq("status", 1)
                .eq("is_pause_sale", 0);

        // 查询skuResult

        ArrayList<Map<String, Object>> infoList = new ArrayList<>();
        if (categoryId != null) {
            queryWrapper.eq("category_id", categoryId);
        }

        if (productId != null) {
            queryWrapper.eq("id", productId);
        }

        com.baomidou.mybatisplus.extension.plugins.pagination.Page<TbProduct> tbProductPage = productMapper.selectPage(page1, queryWrapper);
        tbProductPage.getRecords().forEach(item -> {
            TbProductSkuResult skuResult = productSkuResultRepository.findById(item.getId()).orElse(null);
            List<TbProductSku> tbProductSkus = producSkutMapper.selectList(new LambdaQueryWrapper<TbProductSku>().eq(TbProductSku::getIsDel, 0)
                    .eq(TbProductSku::getIsPauseSale, 0)
                            .eq(TbProductSku::getProductId, item.getId())
                    .eq(TbProductSku::getIsGrounding, 1)
                    .select(TbProductSku::getId, TbProductSku::getSpecSnap, TbProductSku::getStockNumber, TbProductSku::getSalePrice, TbProductSku::getSuit));

            String tagSnap = null;
            if (skuResult != null) {
                tagSnap = skuResult.getTagSnap();
            }
            List<String> result = new ArrayList<>();

            if (StrUtil.isNotBlank(tagSnap)) {
                JSONArray tagSnaps = JSONObject.parseArray(tagSnap);
                List<List<String>> valuesList = new ArrayList<>();

                // 提取所有 value 的列表
                for (int i = 0; i < tagSnaps.size(); i++) {
                    JSONObject jsonObject = tagSnaps.getJSONObject(i);
                    String[] values = jsonObject.getString("value").split(",");
                    valuesList.add(Arrays.asList(values));
                }
                // 生成所有可能的排列组合
                generateCombinations(valuesList, 0, new ArrayList<>(), result);

            }
            ArrayList<Map<String, Object>> specList = new ArrayList<>();

            tbProductSkus.forEach(item2 -> {
                Map<String, Object> itemMap = BeanUtil.beanToMap(item2, false, true);

                if (item.getIsDistribute().equals(1)) {
                    itemMap.put("stockNumber", item.getStockNumber());
                }else {
                    itemMap.put("stockNumber", item2.getStockNumber());
                }
                specList.add(itemMap);
            });

            ArrayList<HashMap<String, Object>> otherVal = new ArrayList<>();
            for (String res : result) {
                boolean found = false;
                for (Map<String, Object> spec : specList) {
                    if (spec.get("specSnap")!= null && res.equals(spec.get("specSnap").toString())) {
                        spec.put("isGrounding", true);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    HashMap<String, Object> itemMap = new HashMap<>();
                    itemMap.put("specSnap", res);
                    itemMap.put("skuId", null);
                    itemMap.put("isGrounding", false);
                    otherVal.add(itemMap);
                }
            }
            specList.addAll(otherVal);

            Map<String, Object> map = BeanUtil.beanToMap(item, false, false);
            map.put("skuResult", skuResult);
            map.put("specList", specList);
            infoList.add(map);
        });

        Map<String, Object> map = BeanUtil.beanToMap(tbProductPage, false, false);
        map.put("records", infoList);
        return map;
    }

    private static void generateCombinations(List<List<String>> valuesList, int index, List<String> current, List<String> result) {
        if (index == valuesList.size()) {
            result.add(String.join(",", current));
            return;
        }

        for (String value : valuesList.get(index)) {
            current.add(value);
            generateCombinations(valuesList, index + 1, current, result);
            current.remove(current.size() - 1); // 回溯
        }
    }

    public static void main(String[] args) {

    }
}
