
package com.tmerclub.cloud.product.service;

import com.tmerclub.cloud.api.platform.dto.OfflineHandleEventDTO;
import com.tmerclub.cloud.api.platform.vo.OfflineHandleEventVO;
import com.tmerclub.cloud.api.product.bo.SpuSimpleBO;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.product.dto.SkuStockPointSearchDTO;
import com.tmerclub.cloud.common.product.dto.SpuDTO;
import com.tmerclub.cloud.common.product.dto.StockPointSkuDTO;
import com.tmerclub.cloud.common.product.vo.SkuVO;
import com.tmerclub.cloud.common.product.vo.SpuActivityAppVO;
import com.tmerclub.cloud.common.product.vo.SpuVO;
import com.tmerclub.cloud.common.product.vo.app.SpuAppVO;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.product.dto.SpuPageSearchDTO;
import com.tmerclub.cloud.product.model.Spu;
import com.tmerclub.cloud.product.model.SpuExtension;
import com.tmerclub.cloud.product.vo.SpuCountVO;
import com.tmerclub.cloud.product.vo.SupplierSpuVo;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * spu信息
 *
 * @author tmerclub
 * @date 2020-10-28 15:27:24
 */
public interface SpuService {

    /**
     * 分页获取spu信息列表
     *
     * @param pageDTO 分页参数
     * @param spuDTO
     * @return spu信息列表分页数据
     */
    PageVO<SpuVO> page(PageDTO pageDTO, SpuPageSearchDTO spuDTO);

    /**
     * spu基本信息(国际化信息还没处理，如需用到商品名等国际化的信息，调用接口后需要处理)
     * 获取数据列表：spu、spu国际化、spu详情、skuIds、赠品活动信息
     *
     * @param spuId spu信息id
     * @return spu信息
     */
    SpuVO getBySpuId(Long spuId);

    /**
     * spu基本信息Map, 从Redis中获取，数据来源：getBySpuId()缓存的商品数据
     *
     * @param spuIds spu信息id
     * @return spu信息
     */
    Map<Long, SpuVO> mapSpuByCache(List<Long> spuIds);

    /**
     * spu扩展信息
     *
     * @param spuId spu信息id
     * @return spu信息
     */
    SpuExtension getSpuExtension(Long spuId);

    /**
     * 保存spu信息
     *
     * @param spuDTO spu信息
     */
    void save(SpuDTO spuDTO);

    /**
     * 更新spu信息
     *
     * @param spuDTO spu信息
     */
    void update(SpuDTO spuDTO);

    /**
     * 根据spu信息id删除spu信息
     *
     * @param spuId
     */
    void deleteById(Long spuId);

    /**
     * 根据spuId列表， 批量清除缓存
     *
     * @param spuIds id
     */
    void batchRemoveSpuActivityCache(List<Long> spuIds);

    /**
     * 改变商品状态（上下架）
     *
     * @param spuId
     * @param status
     */
    void changeSpuStatus(Long spuId, Integer status);

    /**
     * 批量改变商品状态（上下架）
     *
     * @param spuIds
     * @param status
     */
    void batchChangeSpuStatus(List<Long> spuIds, Integer status);

    /**
     * 平台下架商品
     *
     * @param spuIds
     * @param status
     * @param sysType
     */
    void batchChangeCommissionSpuStatus(List<Long> spuIds, Integer status, Integer sysType);

    /**
     * 更新商品的信息
     *
     * @param spuDTO
     */
    void updateSpuOrSku(SpuDTO spuDTO);

    /**
     * 更新spu表（canal监听后，会发送更新的消息，更新es中的数据）
     *
     * @param spuIds
     * @param categoryIds
     * @param shopIds
     * @param sysType
     */
    void updateSpuUpdateTime(List<Long> spuIds, List<Long> categoryIds, List<Long> shopIds, Integer sysType);

    /**
     * 获取 spuId列表
     *
     * @param shopCategoryIds 店铺分类id列表
     * @param categoryIds     平台分类Id列表
     * @param brandId         品牌id
     * @param shopId          店铺id
     * @return spuId列表
     */
    List<Long> getSpuIdsBySpuUpdateDTO(List<Long> shopCategoryIds, List<Long> categoryIds, Long brandId, Long shopId);

    /**
     * 商品活动信息
     *
     * @param shopId
     * @param spuId
     * @return
     */
    SpuActivityAppVO spuActivityBySpuId(Long shopId, Long spuId);

    /**
     * 根据店铺id，获取店铺spu列表
     *
     * @param shopId
     * @return
     */
    List<Long> listSpuIdsByShopId(Long shopId);

    /**
     * 根据id获取
     * @param supplierId
     * @return
     */
    SpuCountVO getSpuCountBySupplierId(Long supplierId);

    /**
     * 下线店铺中的商品
     *
     * @param shopId
     */
    void offlineSpuByShopId(Long shopId);

    /**
     * 获取spu列表
     *
     * @param spu
     * @return
     */
    List<SpuVO> list(SpuPageSearchDTO spu);

    /**
     * 更新商品信息
     *
     * @param spu
     */
    void updateSpu(Spu spu);

    /**
     * 平台下架优惠券
     *
     * @param offlineHandleEventDto
     */
    void offline(OfflineHandleEventDTO offlineHandleEventDto);

    /**
     * 获取下线的事件记录
     *
     * @param spuId
     * @return
     */
    OfflineHandleEventVO getOfflineHandleEvent(Long spuId);

    /**
     * 平台审核商家提交的申请
     *
     * @param offlineHandleEventDto
     */
    void audit(OfflineHandleEventDTO offlineHandleEventDto);

    /**
     * 违规活动提交审核
     *
     * @param offlineHandleEventDto
     */
    void auditApply(OfflineHandleEventDTO offlineHandleEventDto);

    /**
     * 根据spuId或者为空直接获取可以参与秒杀活动的商品列表
     *
     * @param spuId  spuId
     * @param shopId 店铺id
     * @return 商品信息
     */
    List<SpuVO> listCanSeckillProd(Long spuId, Long shopId);

    /**
     * 根据运费id获取商品数量
     *
     * @param transportId
     * @return
     */
    Integer countByTransportId(Long transportId);

    /**
     * 变为普通商品
     *
     * @param spuIds
     */
    void changeToNormalSpu(List<Long> spuIds);

    /**
     * 根据分类id与店铺id查询使用该分类的商品数量
     *
     * @param categoryId
     * @param shopId
     * @param sysType
     * @return
     */
    int countByCategoryAndShopId(Long categoryId, Long shopId, Integer sysType);

    /**
     * 商品状态发生改变时，需要处理的事件
     *
     * @param spuIds 商品id
     */
    void handleStatusChange(List<Long> spuIds);

    /**
     * 根据用户id查询商品收藏数量
     *
     * @param userId 用户id
     * @return 商品收藏数量
     */
    Integer countByUserId(Long userId);

    /**
     * 根据商品id列表获取商品名称列表
     *
     * @param spuIds
     * @return
     */
    List<SpuVO> listSpuNameBySpuIds(List<Long> spuIds);


    /**
     * 批量改变商品状态（上下架）
     *
     * @param cidList
     * @param status
     * @param shopId
     * @param sysType
     */
    void batchChangeSpuStatusByCidListAndShopId(List<Long> cidList, Integer status, Long shopId, Integer sysType);

    /**
     * 根据商品id列表获取商品列表
     *
     * @param spuIds
     * @return
     */
    List<SpuVO> listSpuBySpuIds(List<Long> spuIds);

    /**
     * 根据商品id列表获取商品列表
     *
     * @param spuIds
     * @return
     */
    List<SpuVO> listSpuDetailBySpuIds(List<Long> spuIds);

    /**
     * 更新商品数据
     */
    void verifySpuData();

    /**
     * 获取商品信息
     *
     * @param spuId
     * @return
     */
    SpuAppVO prodInfo(Long spuId);

    /**
     * 根据店铺id列表下架商品
     *
     * @param type
     * @param shopIds
     */
    void offlineSpuByShopIds(Integer type, List<Long> shopIds);

    /**
     * 根据商品id设置商品是否置顶
     *
     * @param spuId
     */
    void toTopBySpuId(Long spuId);

    /**
     * 根据基本信息获取商品列表
     *
     * @param spuSimpleBO
     * @return
     */
    List<SpuSimpleBO> listSimple(SpuSimpleBO spuSimpleBO);

    /**
     * 根据基本信息获取商品列表(包括删除商品）
     *
     * @param spuSimpleBO
     * @return
     */
    List<SpuSimpleBO> listSimples(SpuSimpleBO spuSimpleBO);

    /**
     * 移除商品缓存通过商品id
     *
     * @param spuId 商品id
     */
    void removeSpuCacheBySpuId(Long spuId);

    /**
     * 根据店铺id列表获取商品id列表
     *
     * @param shopIds
     * @return
     */
    List<Long> listSpuIdsByShopIds(List<Long> shopIds);

    /**
     * 移除商品中指定的品牌信息
     *
     * @param brandId
     */
    void removeBrandOfSpu(Long brandId);

    /**
     * 校验spu状态
     *
     * @param spuIds
     * @return
     */
    ServerResponseEntity<Void> checkSpuStatus(List<Long> spuIds);

    /**
     * 批量下线商品
     *
     * @param offlineHandleEventDto
     */
    void batchOffile(OfflineHandleEventDTO offlineHandleEventDto);

    /**
     * 根据店铺id和供应商商品id判断店铺是否代销了
     *
     * @param shopId
     * @param supplierSpuId
     * @return
     */
    Integer isCommissionByShopIdAndSpuId(Long shopId, Long supplierSpuId);

    /**
     * 商家代销供应商的商品时获取供应商商品信息
     *
     * @param spuId
     * @param shopId
     * @return
     */
    SupplierSpuVo getSupplierInfoBySpuId(Long spuId, Long shopId);

    /**
     * 当供货价高于代销价时下架商品(sku供货价)
     *
     * @param skuId
     * @param price
     */
    void soldOutSpu(Long skuId, Long price);

    /**
     * 商家单个/批量导入供应商商品
     *
     * @param supplierSpuId
     * @return
     */
    List<Long> importSupplierSpu(List<Long> supplierSpuId);

    /**
     * 根据代销设置设置代销商品的售价
     *
     * @param skuVO
     * @return
     */
    Long setPriceFee(SkuVO skuVO);

    /**
     * 根据店铺id和供应商商品id获取代销商品信息
     *
     * @param shopId
     * @param supplierSpuId
     * @return
     */
    SpuVO getSpuByShopIdAndSupplierSpuId(Long shopId, Long supplierSpuId);

    /**
     * 获取代销商品spu信息列表
     *
     * @param spu
     * @return spu信息列表
     */
    List<SpuVO> supplierSpuList(SpuPageSearchDTO spu);

    /**
     * 根据供应商id批量获取商家代销商品信息
     *
     * @param supplierId
     * @return
     */
    List<SpuVO> listMerchantSpuIdsBySupplierId(Long supplierId);

    /**
     * 根据店铺id和供应商商品id列表批量获取代销商品信息
     *
     * @param shopId
     * @param supplierSpuIds
     * @return
     */
    List<SpuVO> listSpuByShopIdAndSupplierSpuId(Long shopId, List<Long> supplierSpuIds);

    /**
     * 根据供应商id、发布时间和商品类型(是否已被代销)批量获取商品信息
     *
     * @param supplierId
     * @param createTime
     * @param supplierSpuType
     * @return
     */
    List<SpuVO> getSpuIdsBySupplierIdAndSupplierSpuType(Long supplierId, Date createTime, Integer supplierSpuType);

    /**
     * 供应商修改供货价时修改代销商品价格
     *
     * @param spuId
     * @param price
     * @param marketPriceFee
     */
    void soldOutSpuBySpu(Long spuId, Long price, Long marketPriceFee);

    /**
     * 根据供应商Id下线供应商店铺的商品
     *
     * @param supplierId
     * @return
     */
    void offlineSpuBySupplierId(Long supplierId);

    /**
     * 根据供应商商品id获取供应商发货代销商品信息
     *
     * @param supplierSpuId
     * @return
     */
    List<SpuVO> listSpuBySupplierSpuId(Long supplierSpuId);

    /**
     * 获取代销商品 供应商商品更新后代销商品是否已同步更新 值
     *
     * @param spuIds
     * @return
     */
    List<SpuVO> getSpuIsSynUpdate(List<Long> spuIds);

    /**
     * 根据供应商商品id获取代销商品id集合
     *
     * @param supplierId
     * @return
     */
    List<Long> getSupIdListBySupplierId(Long supplierId);

    /**
     * 批量设置供应商商品更新后代销商品是否已同步更新值
     *
     * @param spuIds
     * @param isSynUpdate
     */
    void batchChangeSynUpdate(List<Long> spuIds, Integer isSynUpdate);

    /**
     * 批量修改代销商品发货方式
     *
     * @param spuIds
     * @param deliverType
     */
    void batchUpdateCommissionSpuDeliverType(List<Long> spuIds, Integer deliverType);

    /**
     * 供应商商品变更后对应下架不同类型的代销商品
     *
     * @param supplierSpuId
     * @param commissionSpuOffType
     */
    void supplierSpuUpdateLaterOffSpu(Long supplierSpuId, Integer commissionSpuOffType);

    /**
     * 商家更新代销设置时，更新代销商品的价格
     *
     * @param shopId
     */
    void updateManualPriceCommissionSpuPrice(Long shopId);
    /**
     * spu基本信息(国际化信息还没处理，如需用到商品名等国际化的信息，调用接口后需要处理)
     *
     * @param spuIds
     * @return spu信息
     */
    List<SpuVO> getBySpuIds(List<Long> spuIds);

    /**
     * 据供应商id列表下架商品
     *
     * @param supplierIdsToStop
     */
    void batchChangeSpuStatusToDisableBySupplierIds(List<Long> supplierIdsToStop);

    /**
     * 根据供应商品id获取发货方式为供应商发货代销商品Id集合
     *
     * @param supplierSpuId
     * @return
     */
    List<SpuVO> getCommissionSpuList(Long supplierSpuId);

    /**
     * 供应商品更新品牌或者排序时,同步更新代销商品的品牌或排序upadte
     *
     * @param brandId
     * @param seq
     * @param supplierSpuId
     */
    void syncUpdateCommissionSpuBrandOrSeq(Long brandId, Integer seq, Long supplierSpuId);

    /**
     * 分页查询spu及其sku信息
     *
     * @param pageDTO
     * @param spuDTO
     * @return
     */
    PageVO<SpuVO> pageSpuSku(PageDTO pageDTO, SpuDTO spuDTO);

    /**
     * 添加采购订单时未导入的供应商品自动导入
     *
     * @param spuVOList
     * @param sysType
     * @param userId
     */
    void voluntarilyImportSupplierSpu(List<SpuVO> spuVOList, Integer sysType, Long userId);

    /**
     * 初次审核发布的商品
     *
     * @param eventDTO
     */
    void auditSpu(OfflineHandleEventDTO eventDTO);

    /**
     * 获取供应商库存预警数量
     *
     * @param supplierId
     * @return
     */
    Long stockWarningCount(Long supplierId);

    /**
     * 获取核销时间过期的虚拟商品并进行下架操作
     *
     * @return 过期的虚拟商品
     */
    List<SpuVO> handleExpireVirtualProd();

    /**
     * 设置属性
     * @param spuVO
     */
    void loadSpuAttrs(SpuVO spuVO);

    /**
     * 根据店铺id更新商品（canal监听后，会发送更新的消息，更新es中的数据）
     * @param shopId 店铺id
     * @param sysType 系统类型
     */
    void updateSpuByShopId(Long shopId, Integer sysType);

    /**
     * 获取店铺中指定供应商商品的代销商品列表
     * @param shopId
     * @param supplierSpuIds
     * @return
     */
    List<SpuVO> listShopSpuBySupplierSpuIds(Long shopId, List<Long> supplierSpuIds);

    /**
     * 分页获取库存点关联的商品数据
     * @param pageDTO
     * @param spuDTO
     * @return
     */
    PageVO<SpuVO> pageStockPointSpu(PageDTO pageDTO, StockPointSkuDTO spuDTO);

    /**
     * 分页获取供应商库存点商品
     * @param pageDTO 分页参数
     * @param searchDTO 查询参数
     * @return
     */
    PageVO<SpuVO> pageSupplierStockPointSpu(PageDTO pageDTO, SkuStockPointSearchDTO searchDTO);

    /**
     * 初始化商品关联数据
     */
    void intiStockPointSKu();

    /**
     * 获取状态正常的商品数量
     * @param spuIds
     * @param skuIds
     * @return
     */
    int countNormalSpuBySpuIds(Set<Long> spuIds);
}
