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

package com.yami.shop.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.bean.app.dto.ProductDto;
import com.yami.shop.bean.app.dto.SkuDto;
import com.yami.shop.bean.app.dto.TagProductDto;
import com.yami.shop.bean.app.param.SearchParam;
import com.yami.shop.bean.dto.*;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.event.GetTransportNamesEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.*;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.model.OfflineHandleEvent;
import com.yami.shop.bean.model.Product;
import com.yami.shop.bean.model.Sku;
import com.yami.shop.bean.vo.SimilarProdListVo;
import com.yami.shop.bean.vo.SkuBuyTogetherOftenVo;
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.common.util.Json;
import com.yami.shop.common.util.PageParam;
//import com.yami.shop.common.util.PoiExcelUtil;
import com.yami.shop.dao.*;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private final ProductMapper productMapper;
    private final LabelMapper labelMapper;
    private final BrandService brandService;
    private final CategoryService categoryService;
    private final ApplicationContext applicationContext;
    private final SkuMapper skuMapper;
    private final OfflineHandleEventService offlineHandleEventService;


//    @Override
//    public Product getById(Long prodId, Integer platform) {
//        return productMapper.doGetById(prodId, platform);
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveProduct(Product product) {
        productMapper.insert(product);
        if (CollectionUtil.isNotEmpty(product.getSkuList())) {
            skuMapper.insertBatch(product.getProdId(), product.getSkuList());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
            @CacheEvict(cacheNames = "product", key = "#product.prodId"),
            @CacheEvict(cacheNames = "skuList", key = "#product.prodId")
    })
    public void updateProduct(Product product, Product dbProduct) {
        // 使用保存或更新，可以仅更新非null的数据（弃用，会引发bug,选择品牌后没法取消）
//        saveOrUpdate(product);
        productMapper.updateProduct(product);
        List<Long> dbSkuIds = dbProduct.getSkuList().stream().map(Sku::getSkuId).collect(Collectors.toList());
        // 2019/04/c0244be79909484fb67bc6d5f70cae18.jpg
//        if (!Objects.equals(dbProduct.getPic(), product.getPic()) && StrUtil.isNotBlank(dbProduct.getPic())) {
//            // 删除数据库中的商品图片
//            attachFileService.deleteFile(dbProduct.getPic());
//        }
        // 将所有该商品的sku标记为已删除状态
        skuMapper.deleteByProdId(product.getProdId());

        // 接口传入sku列表
        List<Sku> skuList = product.getSkuList();

        if (CollectionUtil.isEmpty(skuList)) {
            return;
        }

        List<Sku> insertSkuList = new ArrayList<>();
        for (Sku sku : skuList) {
            sku.setIsDelete(0);
            // 如果数据库中原有sku就更新，否者就插入
            if (dbSkuIds.contains(sku.getSkuId())) {
                skuMapper.updateById(sku);
            } else {
//                if (dbProduct.getGroupActivityId() != null && dbProduct.getGroupActivityId() != 0) {
                if (dbProduct.getProdType() != null && dbProduct.getProdType().equals(ProdType.PROD_TYPE_GROUP.value())) {
                    throw new GlobalException("商品正在参与拼团活动，无法修改规格");
                }
                insertSkuList.add(sku);
            }
        }
        // 批量插入sku
        if (CollectionUtil.isNotEmpty(insertSkuList)) {
            skuMapper.insertBatch(product.getProdId(), insertSkuList);
        }
    }


    /**
     * 这里的缓存 1800秒消失，详情RedisCacheConfig这里的配置
     * 当秒杀的时候，并不更新这里的缓存，所以库存会滞后，但是半个小时后缓存消失，又会重新获取
     *
     * @param prodId
     * @return
     */
    @Override
    public Product getProductByProdId(Long prodId) {
        return productMapper.selectById(prodId);
    }

    @Override
    public Product getProductByProdId(Long prodId, Long channelId, Long shopId) {
        return productMapper.doGetById(prodId, channelId, shopId);
    }
    @Override
    public Product getProductByProdIdAndShopId(Long prodId, Long shopId) {
        return productMapper.doGetByShopId(prodId, shopId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
            @CacheEvict(cacheNames = "product", key = "#prodId"),
            @CacheEvict(cacheNames = "skuList", key = "#prodId")
    })
    public void removeProductByProdId(Long prodId) {
//        Product dbProduct = getProductByProdId(prodId);

        // 将商品的状态变成-1（逻辑删除）
        Product product = new Product();
        product.setProdId(prodId);
        product.setStatus(-1);
        saveOrUpdate(product);

        skuMapper.deleteByProdId(prodId);
    }

    @Override
    @Caching(evict = {
            @CacheEvict(cacheNames = "product", key = "#prodId"),
            @CacheEvict(cacheNames = "skuList", key = "#prodId")
    })
    public void removeProductCacheByProdId(Long prodId) {


    }

    @Override
    public IPage<ProductDto> pageByPutawayTime(IPage<ProductDto> page, String lat, String lon, String distance) {
        if (StringUtils.isNotEmpty(lat) && StringUtils.isNotEmpty(lon) && StringUtils.isNotEmpty(distance)) {
            List<ShopDetail> shops = productMapper.queryShop(lat, lon, distance);
            List<Long> list;
            if (CollectionUtil.isNotEmpty(shops)) {
                list = shops.stream().map(ShopDetail::getShopId).collect(Collectors.toList());
                return productMapper.pageByPutawayTimeNew(page, list);
            }
        } else {
            return productMapper.pageByPutawayTime(page);
        }
        return new Page<>();
    }

    @Override
    public IPage<ProductDto> pageByScore(IPage<ProductDto> page) {


        return productMapper.pageByScore(page);
    }


    @Override
    public IPage<ProductDto> pageByTagId(Page<ProductDto> page, Long tagId) {
        return productMapper.pageByTagId(page, tagId);
    }


    @Override
    public IPage<ProductDto> moreBuyProdList(Page<ProductDto> page) {
        return productMapper.moreBuyProdList(page);
    }

    @Override
    public IPage<SearchProdDto> getSearchProdDtoPageByProdName(PageParam<SearchProdDto> page, SearchParam searchParam) {

        if (searchParam.getShopId() == null){
            return new Page<>();
        }
        if (searchParam.getChannelId() == null){
            searchParam.setChannelId(3L);
        }
        return productMapper.getSearchProdDtoPageByProdName(page, searchParam);

    }

    @Override
    public List<TagProductDto> tagProdList() {
        return productMapper.tagProdList();
    }

    @Override
    public IPage<ProductDto> pageByDiscountId(Page<ProductDto> page, Long discountId) {
        return productMapper.pageByDiscountId(page, discountId);
    }

    @Override
    public IPage<ProductDto> collectionProds(PageParam page, String userId) {
        return productMapper.collectionProds(page, userId);
    }

    @Override
    public List<ProdAndSkuListsDto> getProdAndSkuLists(List<Long> prodIds) {
        return productMapper.getProdAndSkuLists(prodIds);
    }

    @Override
    public void updateProductToGroup(Long groupActivityId, List<Long> prodIds) {
        productMapper.updateProductToGroup(groupActivityId, prodIds);
    }

    @Override
    public void updateProductToUnGroup(Long prodId) {
        productMapper.updateProductToUnGroup(prodId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditApply(Long eventId, Long prodId, String reapplyReason) {
        // 更新商品为待审核状态
        productMapper.updateToApply(prodId);
        // 更新事件状态
        offlineHandleEventService.updateToApply(eventId, reapplyReason);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void prodAudit(OfflineHandleEventAuditParam offlineHandleEventAuditParam, Long sysUserId) {
        // 审核通过,更新商品状态
        if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.AGREE_BY_PLATFORM.getValue())) {
            productMapper.updateToShopOffline(offlineHandleEventAuditParam.getHandleId());
        } else if (Objects.equals(offlineHandleEventAuditParam.getStatus(), OfflineHandleEventStatus.DISAGREE_BY_PLATFORM.getValue())) {
            productMapper.updateToOffline(offlineHandleEventAuditParam.getHandleId());
        }
        offlineHandleEventService.auditOfflineEvent(offlineHandleEventAuditParam, sysUserId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void offline(Long prodId, String offlineReason, Long sysUserId) {
        Product product = getProductByProdId(prodId);

        // 添加下线处理记录
        Date now = new Date();
        OfflineHandleEvent offlineHandleEvent = new OfflineHandleEvent();
        offlineHandleEvent.setHandleType(OfflineHandleEventType.PROD.getValue());
        offlineHandleEvent.setHandleId(product.getProdId());
        offlineHandleEvent.setHandlerId(sysUserId);
        offlineHandleEvent.setOfflineReason(offlineReason);
        offlineHandleEvent.setCreateTime(now);
        offlineHandleEvent.setShopId(product.getShopId());
        offlineHandleEvent.setStatus(OfflineHandleEventStatus.OFFLINE_BY_PLATFORM.getValue());
        offlineHandleEvent.setUpdateTime(now);
        offlineHandleEventService.save(offlineHandleEvent);

        // 更新活动状态为下线
        productMapper.updateToOffline(prodId);
    }

    @Override
    public IPage<Product> getPageAngShopName(PageParam<Product> page, ProductParam product) {
        return productMapper.getPageAndShopName(page, product);
    }


    @Override
    public void exportProd(ProductExportParam productParam, HttpServletResponse response, Long shopId) {
        List<ProductExportParam> products = productMapper.listProdsByProdParam(productParam);
        createExcel(products, response, shopId);
    }

    private void createExcel(List<ProductExportParam> products, HttpServletResponse response, Long shopId) {

        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getBigWriter();
        // 待发货
        String[] hearder = {"产品名称", "平台分类", "店铺分类", "所属品牌", "产品卖点", "配送方式", "运费设置", "产品状态",
                "规格名称", "商品名称", "销售属性组合字符串 格式是p1:v1;p2:v2", "原价", "价格", "积分价格",
                "库存", "商家编码", "商品条形码", "商品重量", "商品体积"};
        Sheet sheet = writer.getSheet();
        sheet.setColumnWidth(0, 60 * 256);
        sheet.setColumnWidth(1, 20 * 256);
        sheet.setColumnWidth(2, 20 * 256);
        sheet.setColumnWidth(8, 60 * 256);
        sheet.setColumnWidth(9, 60 * 256);
        sheet.setColumnWidth(10, 60 * 256);

        writer.merge(hearder.length - 1, "销售信息整理");
        writer.writeRow(Arrays.asList(hearder));
        // 限制商家分类和平台分类
        List<Category> categories = categoryService.list(new LambdaQueryWrapper<Category>()
                .eq(Category::getShopId, 0L).eq(Category::getGrade, 2));
        if (CollectionUtils.isNotEmpty(categories)) {
            String[] categoryName = new String[categories.size()];
            for (int i = 0; i < categories.size(); i++) {
                categoryName[i] = categories.get(i).getCategoryName();
            }
            createDropDownList(sheet, categoryName, 2, 50000, 1, 1);
        }
        List<Category> shopCategories = categoryService.listByShopId(shopId);
        if (CollectionUtils.isNotEmpty(shopCategories)) {
            String[] categoryName = new String[shopCategories.size()];
            for (int i = 0; i < shopCategories.size(); i++) {
                categoryName[i] = shopCategories.get(i).getCategoryName();
            }
            createDropDownList(sheet, categoryName, 2, 50000, 2, 2);
        }
        // 限制物流方式
        String[] dvyTypes = {"商家邮寄", "用户自提", "同城配送", "商家邮寄,用户自提", "商家邮寄,同城配送", "同城配送,用户自提", "商家邮寄,用户自提,同城配送"};
        createDropDownList(sheet, dvyTypes, 2, 50000, 5, 5);
        // 限制品牌选择
        List<Brand> brands = brandService.list(new LambdaQueryWrapper<Brand>().eq(Brand::getStatus, 1));
        if (CollectionUtils.isNotEmpty(brands)) {
            String[] categoryName = new String[brands.size()];
            for (int i = 0; i < brands.size(); i++) {
                categoryName[i] = brands.get(i).getBrandName();
            }
            createDropDownList(sheet, categoryName, 2, 50000, 3, 3);
        }
        List<TransportParam> transportParams = new ArrayList<>();
        applicationContext.publishEvent(new GetTransportNamesEvent(transportParams, shopId));
        if (CollectionUtils.isNotEmpty(transportParams)) {
            List<String> transportNameList = new ArrayList<>();
            transportParams.forEach(transportParam -> transportNameList.add(transportParam.getTransName()));
            String[] transportNames = transportNameList.toArray(new String[transportNameList.size()]);
            createDropDownList(sheet, transportNames, 2, 50000, 6, 6);
        }
        String[] statusStr = {"下架", "上架"};
        createDropDownList(sheet, statusStr, 2, 50000, 7, 7);
        int row = 1;
        if (CollectionUtils.isNotEmpty(products)) {
            for (ProductExportParam prod : products) {
                List<Sku> skuList = prod.getSkuList();
                int firstRow = row + 1;
                int lastRow = row + skuList.size();
                int col = -1;
                // 产品图片
//                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getPic());
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getProdName());
                // 平台分类
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getCategoryName());
                // 店铺分类
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getShopCategoryName());
                // "所属品牌"
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getBrandName());
                // "产品卖点"
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getBrief());
                Product.DeliveryModeVO deliveryModeVO = Json.parseObject(prod.getDeliveryMode(), Product.DeliveryModeVO.class);
                StringBuilder deliveryMode = new StringBuilder();
                if (deliveryModeVO != null) {
                    if (deliveryModeVO.getHasCityDelivery() != null && deliveryModeVO.getHasCityDelivery()) {
                        deliveryMode.append("同城配送，");
                    }
                    if (deliveryModeVO.getHasUserPickUp() != null && deliveryModeVO.getHasUserPickUp()) {
                        deliveryMode.append("用户自提，");
                    }
                    if (deliveryModeVO.getHasShopDelivery() != null && deliveryModeVO.getHasShopDelivery()) {
                        deliveryMode.append("商家邮寄，");
                    }
                    deliveryMode.deleteCharAt(deliveryMode.length() - 1);
                }
                //TODO 配送方式
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, deliveryMode);
                // 运费设置
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getTransName());
                // 产品状态
                mergeIfNeed(writer, firstRow, lastRow, ++col, col, prod.getStatus() == 1 ? "上架" : "下架");
                for (Sku sku : skuList) {
                    int index = col;
                    row++;
                    // 规格名称
                    writer.writeCellValue(++index, row, sku.getSkuName());
                    // 商品名称
                    writer.writeCellValue(++index, row, sku.getProdName());
                    // 属性名称
                    writer.writeCellValue(++index, row, sku.getProperties());
                    // 规格图片
//                    writer.writeCellValue(++index, row, sku.getPic());
                    // 原价
                    writer.writeCellValue(++index, row, sku.getOriPrice());
                    // 实际价格
                    writer.writeCellValue(++index, row, sku.getPrice());
                    // 积分价格
                    writer.writeCellValue(++index, row, sku.getSkuScore());
                    // 库存
                    writer.writeCellValue(++index, row, sku.getStocks());
                    // 商家编码
                    writer.writeCellValue(++index, row, sku.getPartyCode());
                    // 商家条形码
                    writer.writeCellValue(++index, row, sku.getModelId());
                    // 商品重量
                    writer.writeCellValue(++index, row, sku.getWeight());
                    // 商品体积
                    writer.writeCellValue(++index, row, sku.getVolume());
                }
            }
        }
        writeExcel(response, writer);
    }

    @Override
    public void downloadModel(HttpServletResponse response, Long shopId) {
        createExcel(null, response, shopId);
    }

    @Override
    public Object parseFile(MultipartFile file, Long shopId) throws Exception {
        return null;
    }
//    @Override
//    public Object parseFile(MultipartFile file, Long shopId) throws Exception {
//        //读取工作簿
//        Workbook workBook = WorkbookFactory.create(file.getInputStream());
//        //读取工作表
//        Sheet sheet = workBook.getSheetAt(0);
//        int rowNumber = sheet.getPhysicalNumberOfRows();
//
//        //校验是否填写内容
//        if (rowNumber <= 2) {
//            throw new GlobalException("文件无内容！");
//        }
//        // * 2.1不是Excel文件，直接返回提示信息
//        if (!(file.getOriginalFilename().contains("xls") || file.getOriginalFilename().contains("xlsx"))) {
//            // 格式错误
//            throw  new YamiShopBindException("文件格式错误");
//        }
//
//        //TODO 如果三级分类需要获取最底层的分类
//        // 获取平台分类map
//        List<Category> categories = categoryService.list(new LambdaQueryWrapper<Category>()
//                .eq(Category::getShopId,0).eq(Category::getGrade,2));
//        // 如果重复的key取最后一个的值
//        Map<String, Long> categoryMap = categories.stream().collect(Collectors.toMap(Category::getCategoryName, Category::getCategoryId,(key1 , key2)-> key2));
//
//        // 获取店铺分类map
//        List<Category> shopCategories = categoryService.listByShopId(shopId);
//        // 如果重复的key取最后一个的值
//        Map<String, Long> shopCategoryMap = shopCategories.stream().collect(Collectors.toMap(Category::getCategoryName, Category::getCategoryId,(key1 , key2)-> key2));
//
//        // 获取品牌map
//        List<Brand> brands = brandService.list(new LambdaQueryWrapper<Brand>().eq(Brand::getStatus, 1));
//        Map<String, Long> brandMap = brands.stream().collect(Collectors.toMap(Brand::getBrandName, Brand::getBrandId,(key1 , key2)-> key2));
//
//        // 获取运费模板map
//        List<TransportParam> transportParams = new ArrayList<>();
//        applicationContext.publishEvent(new GetTransportNamesEvent(transportParams,shopId));
//        Map<String, Long> transportMap = transportParams.stream().collect(Collectors.toMap(TransportParam::getTransName, TransportParam::getTransportId,(key1 , key2)-> key2));
//
//        List<Product> products = new ArrayList<>();
//        List<Sku> skuList = new ArrayList<>();
//        Date date = new Date();
//        Integer totalStocks = 0;
//        double price = 0.0;
//        double oriPrice = 0.0;
//        Integer scorePrice = 0;
//        int insertRows = 0;
//        Product product = new Product();
//        //循环读取每一行数据并校验
//        for (int i = 2; i < rowNumber; i++) {
//            try {
//                //读取行
//                Row row = sheet.getRow(i);
////                String[] hearder = { "产品名称", "平台分类", "店铺分类", "所属品牌", "产品卖点", "配送方式","运费设置",
////                        "规格名称","商品名称", "销售属性组合字符串 格式是p1:v1;p2:v2", "原价", "价格", "积分价格",
////                        "库存","商家编码","商品条形码" ,"商品重量", "商品体积","产品状态"};
//                String prodName = Objects.isNull(row.getCell(0))? "":row.getCell(0).getStringCellValue();
//                String category = Objects.isNull(row.getCell(1))? "":row.getCell(1).getStringCellValue();
//                String  shopCategory = Objects.isNull(row.getCell(2))? "":row.getCell(2).getStringCellValue();
//                String brandName = Objects.isNull(row.getCell(3))? "":row.getCell(3).getStringCellValue();
//                String brif = Objects.isNull(row.getCell(4))? "":row.getCell(4).getStringCellValue();
//                String dvyType = Objects.isNull(row.getCell(5))? "":row.getCell(5).getStringCellValue();
//                String transportName = Objects.isNull(row.getCell(6))? "":row.getCell(6).getStringCellValue();
//                String statusStr = Objects.isNull(row.getCell(7))? "":row.getCell(7).getStringCellValue();
//                if(StrUtil.isNotBlank(prodName) || !PoiExcelUtil.isMergedRegion(sheet,i,0)) {
//                    skuList = new ArrayList<>();
//                    product = new Product();
//                    totalStocks = 0;
//                    oriPrice = 0.0;
//                    scorePrice = 0;
//                    price = 0.0;
//                    insertRows++;
//                    product.setShopId(shopId);
//                    product.setProdName(prodName);
//                    product.setCategoryId(categoryMap.get(category));
//                    product.setShopCategoryId(shopCategoryMap.get(shopCategory));
//                    product.setBrandId(brandMap.get(brandName));
//                    product.setBrief(brif);
//                    product.setDeliveryMode(getDvyType(dvyType));
//                    product.setDeliveryTemplateId(transportMap.get(transportName));
//                    //TODO 差商品的图片
//                    product.setStatus(Objects.equals(statusStr, "上架") ? ProdStatusEnums.NORMAL.getValue() : ProdStatusEnums.SHOP_OFFLINE.getValue());
//                    product.setPutawayTime(Objects.equals(statusStr, "上架") ? date : null);
//                    product.setCreateTime(date);
//                    product.setUpdateTime(date);
//                    product.setVersion(0);
//                    // 商品销量设置为0
//                    product.setSoldNum(0);
//                    product.setProdType(ProdType.PROD_TYPE_NORMAL.value());
//                    product.setActivityId(0L);
//                    product.setPic("2020/07/f29c335ff19746cda1025f363dcc00cf.png");
//                    product.setImgs("2020/07/f29c335ff19746cda1025f363dcc00cf.png");
//
//                    products.add(product);
//                }
//                String[] hearder = { "产品名称", "平台分类", "店铺分类", "所属品牌", "产品卖点", "配送方式","运费设置","产品状态",
//                        "规格名称","商品名称", "销售属性组合字符串 格式是p1:v1;p2:v2", "原价", "价格", "积分价格",
//                        "库存","商家编码","商品条形码" ,"商品重量", "商品体积"};
//                String  skuName = Objects.isNull(row.getCell(8))? "":row.getCell(8).getStringCellValue();
//                String skuProdName = Objects.isNull(row.getCell(9))? "":row.getCell(9).getStringCellValue();
//                String  properties = Objects.isNull(row.getCell(10))? "":row.getCell(10).getStringCellValue();
//                double skuOriPrice = Objects.isNull(row.getCell(11))? 0.0:row.getCell(11).getNumericCellValue();
//                double skuPrice = Objects.isNull(row.getCell(12))? 0.0:row.getCell(12).getNumericCellValue();
//                Integer skuScorePrice = Integer.valueOf(StrUtil.isBlank(row.getCell(13).getStringCellValue())? "0":row.getCell(13).getStringCellValue());
//                Integer stocks = Objects.isNull(row.getCell(14))? 0:(int)(row.getCell(14).getNumericCellValue());
//                String partyCode = "";
//                if(Objects.nonNull(row.getCell(15))) {
//                    row.getCell(15).setCellType(CellType.STRING);
//                    partyCode  = row.getCell(15).getStringCellValue();
//                }
//                String modelId = "";
//                if(Objects.nonNull(row.getCell(15))) {
//                    row.getCell(16).setCellType(CellType.STRING);
//                    modelId  = row.getCell(15).getStringCellValue();
//                }
//                double weight = Objects.isNull(row.getCell(17))? 0.0:row.getCell(17).getNumericCellValue();
//                double volume = Objects.isNull(row.getCell(18))? 0.0:row.getCell(18).getNumericCellValue();
//                oriPrice = Objects.equals(oriPrice ,0.0) ? skuOriPrice:oriPrice;
//                price = Objects.equals(price ,0.0) ? skuPrice:price;
//
//                Sku sku = new Sku();
//                sku.setSkuName(skuName);
//                sku.setProdName(skuProdName);
//                sku.setProperties(properties);
//                sku.setOriPrice(skuOriPrice);
//                sku.setPrice(skuPrice);
//                sku.setStocks(stocks);
//                sku.setSkuScore(skuScorePrice);
//                sku.setModelId(modelId);
//                sku.setPartyCode(partyCode);
//                sku.setVolume(volume);
//                sku.setUpdateTime(date);
//                sku.setWeight(weight);
//                sku.setVersion(1);
//                sku.setIsDelete(0);
//                sku.setStatus(1);
//                skuList.add(sku);
//                // 如果prodName为空并且为合并行则为一个prod
//                totalStocks += stocks;
//                if(price > skuPrice) {
//                    oriPrice = skuOriPrice;
//                    price = skuPrice;
//                    scorePrice = skuScorePrice;
//                }
//                product.setOriPrice(oriPrice);
//                product.setScorePrice(scorePrice);
//                product.setPrice(price);
//                product.setTotalStocks(totalStocks);
//                product.setSkuList(skuList);
//            } catch (Exception e) {
//                //错误信息提示
//                System.out.println("第" + (i + 1) + "行数据有错误," + e.getMessage());
//            }
//        }
//        workBook.close();
//        //不为空批量导入
//        if(CollectionUtils.isNotEmpty(products)){
//            saveBatch(products);
////            List<Sku> skuDb = new ArrayList<>();
//            for (Product productDb : products) {
//                List<Sku> skus = productDb.getSkuList();
//                skuMapper.insertBatch(productDb.getProdId(),skus);
////                skus.forEach(sku -> sku.setProdId(product.getProdId()));
////                skuDb.addAll(skus);
//            }
////            skuMapper.save(skuDb);
//                return "检查到" + insertRows + "条商品，成功导入" + products.size() + "条卡密！";
//            }
//        return "数据错误!导入0条";
//    }

    @Override
    public IPage<Product> pageProducts(PageParam<Product> page, ProductParam product) {
        return productMapper.pageProducts(page, product);
    }

    @Override
    public IPage<Product> listRelatedProducts(ListRelatedProductsDto listRelatedProductsDto) {
        IPage<Product> products = null;
        if (null == listRelatedProductsDto.getProdName()) {
            products = page(new Page<>(listRelatedProductsDto.getCurrent(), listRelatedProductsDto.getSize()), new LambdaQueryWrapper<Product>()
                    .eq(Product::getShopCategoryId, listRelatedProductsDto.getShopCategoryId())
                    .orderByDesc(Product::getCreateTime));
        } else {
            products = page(new Page<>(listRelatedProductsDto.getCurrent(), listRelatedProductsDto.getSize()), new LambdaQueryWrapper<Product>()
                    .eq(Product::getShopCategoryId, listRelatedProductsDto.getShopCategoryId())
                    .orderByDesc(Product::getCreateTime)
                    .like(Product::getProdName, listRelatedProductsDto.getProdName()));
        }
        return products;
    }

    @Override
    public boolean cancelRelatedProducts(long shopId, long productId) {
        Product product = productMapper.selectOne(Wrappers.<Product>lambdaQuery()
                .eq(Product::getProdId, productId)
                .eq(Product::getShopId, shopId));
        if (product != null) {
            product.setShopCategoryId(0L);
            productMapper.updateById(product);
            return true;
        }
        return false;
    }

    @Override
    public boolean relatedProducts(long shopId, List<Long> productId, long shopCategoryId) {
        productId.forEach(id -> {
            Product product = productMapper.selectOne(Wrappers.<Product>lambdaQuery()
                    .eq(Product::getProdId, id)
                    .eq(Product::getShopId, shopId));
            if (product != null) {
                product.setShopCategoryId(shopCategoryId);
                productMapper.updateById(product);
            } else {
                throw new GlobalException("关联失败！");
            }
        });
        return true;
    }

    @Override
    public IPage<Product> listUnRelatedProducts(ListUnRelatedProductsDTO listUnRelatedProductsDTO) {
        IPage<Product> products = null;
        if (null == listUnRelatedProductsDTO.getProdName()) {
            products = page(new Page<>(listUnRelatedProductsDTO.getCurrent(), listUnRelatedProductsDTO.getSize()), new LambdaQueryWrapper<Product>()
                    .eq(Product::getShopId, listUnRelatedProductsDTO.getShopId())
                    .eq(Product::getShopCategoryId, 0)
                    .orderByDesc(Product::getCreateTime));
        } else {
            products = page(new Page<>(listUnRelatedProductsDTO.getCurrent(), listUnRelatedProductsDTO.getSize()), new LambdaQueryWrapper<Product>()
                    .eq(Product::getShopId, listUnRelatedProductsDTO.getShopId())
                    .eq(Product::getShopCategoryId, 0)
                    .orderByDesc(Product::getCreateTime)
                    .like(Product::getProdName, listUnRelatedProductsDTO.getProdName()));
        }
        return products;
    }

    @Override
    public IPage<CategoryProductParam> listProdByCategoryIdAndShopId(ProdByCategoryIdAndShopIdDTO prodByCategoryIdAndShopIdDTO) {
        IPage<CategoryProductParam> productIPage = productMapper.listProdByCIdAndSId(new Page<>(prodByCategoryIdAndShopIdDTO.getCurrent(), prodByCategoryIdAndShopIdDTO.getSize()),
                prodByCategoryIdAndShopIdDTO);
        productIPage.getRecords().forEach(product -> {
            List<Sku> skuList = skuMapper.listByProdId(product.getProdId());
            product.setSkuList(skuList);
        });
        return productIPage;
    }

    @Override
    public IPage<SimilarProdListVo> similarProdList(Page<Product> page, Long prodId, Long shopId, Long channelId,String userId) {
        IPage<SimilarProdListVo> similarProdListVoIPage = productMapper.similarProdList(page, prodId, shopId, channelId, userId);
        similarProdListVoIPage.getRecords().forEach(similarProdListVo -> {
            List<Sku> skuList = skuMapper.listByProdIdAndPlatform(similarProdListVo.getProdId(),channelId,shopId);
            similarProdListVo.setSkuList(skuList);
        });
        return similarProdListVoIPage;
    }

    /**
     * 创建下拉列表选项
     *
     * @param sheet    所在Sheet页面
     * @param values   下拉框的选项值
     * @param firstRow 起始行（从0开始）
     * @param lastRow  终止行（从0开始）
     * @param firstCol 起始列（从0开始）
     * @param lastCol  终止列（从0开始）
     */
    private void createDropDownList(Sheet sheet, String[] values, int firstRow, int lastRow, int firstCol, int lastCol) {
        DataValidationHelper helper = sheet.getDataValidationHelper();

        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        // 设置下拉框数据
        DataValidationConstraint constraint = helper.createExplicitListConstraint(values);
        DataValidation dataValidation = helper.createValidation(constraint, addressList);

        // Excel兼容性问题
        if (dataValidation instanceof XSSFDataValidation) {
            dataValidation.setSuppressDropDownArrow(true);
            dataValidation.setShowErrorBox(true);
        } else {
            dataValidation.setSuppressDropDownArrow(false);
        }

        sheet.addValidationData(dataValidation);
    }

    /**
     * 如果需要合并的话，就合并
     */
    private void mergeIfNeed(ExcelWriter writer, int firstRow, int lastRow, int firstColumn, int lastColumn, Object content) {
        if (lastRow - firstRow > 0 || lastColumn - firstColumn > 0) {
            writer.merge(firstRow, lastRow, firstColumn, lastColumn, content, false);
        } else {
            writer.writeCellValue(firstColumn, firstRow, content);
        }

    }

    private void writeExcel(HttpServletResponse response, ExcelWriter writer) {
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=1.xls");

        ServletOutputStream servletOutputStream = null;
        try {
            servletOutputStream = response.getOutputStream();
            writer.flush(servletOutputStream);
            servletOutputStream.flush();
        } catch (IORuntimeException | IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
            try {
                if (servletOutputStream != null) {
                    servletOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
