package cn.newfeifan.mall.module.product.dal.mysql.spuapply;


import cn.hutool.core.util.ObjectUtil;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.newfeifan.mall.framework.mybatis.core.mapper.BaseMapperX;
import cn.newfeifan.mall.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
import cn.newfeifan.mall.module.product.dal.dataobject.spuapply.SpuApplyDO;
import cn.newfeifan.mall.module.product.enums.ProductConstants;
import cn.newfeifan.mall.module.product.enums.spu.ProductSpuStatusEnum;
import cn.newfeifan.mall.module.product.enums.spu.SpuApplyCheckStatusEnum;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import org.apache.ibatis.annotations.Mapper;
import cn.newfeifan.mall.module.product.controller.admin.spuapply.vo.*;
import org.apache.ibatis.annotations.Select;

/**
 * 商品spu申请 Mapper
 *
 * @author 非繁人
 */
@Mapper
public interface SpuApplyMapper extends BaseMapperX<SpuApplyDO> {

    default PageResult<SpuApplyDO> selectPage(SpuApplyPageReqVO reqVO) {
        Integer tabType = reqVO.getTabType();
        LambdaQueryWrapperX<SpuApplyDO> wrapper = new LambdaQueryWrapperX<SpuApplyDO>()
                .likeIfPresent(SpuApplyDO::getName, reqVO.getName())
                .eqIfPresent(SpuApplyDO::getKeyword, reqVO.getKeyword())
                .eqIfPresent(SpuApplyDO::getIntroduction, reqVO.getIntroduction())
                .eqIfPresent(SpuApplyDO::getDescription, reqVO.getDescription())
                .eqIfPresent(SpuApplyDO::getProducerArea, reqVO.getProducerArea())
                .eqIfPresent(SpuApplyDO::getSpuType, reqVO.getSpuType())
                .eqIfPresent(SpuApplyDO::getCategoryId, reqVO.getCategoryId())
                .eqIfPresent(SpuApplyDO::getBrandId, reqVO.getBrandId())
                .eqIfPresent(SpuApplyDO::getPicUrl, reqVO.getPicUrl())
                .eqIfPresent(SpuApplyDO::getSliderPicUrls, reqVO.getSliderPicUrls())
                .eqIfPresent(SpuApplyDO::getSort, reqVO.getSort())
                .eqIfPresent(SpuApplyDO::getStatus, reqVO.getStatus())
                .eqIfPresent(SpuApplyDO::getSpecType, reqVO.getSpecType())
                .eqIfPresent(SpuApplyDO::getPrice, reqVO.getPrice())
                .eqIfPresent(SpuApplyDO::getMarketPrice, reqVO.getMarketPrice())
                .eqIfPresent(SpuApplyDO::getCostPrice, reqVO.getCostPrice())
                .eqIfPresent(SpuApplyDO::getStock, reqVO.getStock())
                .eqIfPresent(SpuApplyDO::getDeliveryTypes, reqVO.getDeliveryTypes())
                .eqIfPresent(SpuApplyDO::getDeliveryTemplateId, reqVO.getDeliveryTemplateId())
                .eqIfPresent(SpuApplyDO::getGiveIntegral, reqVO.getGiveIntegral())
                .eqIfPresent(SpuApplyDO::getSubCommissionType, reqVO.getSubCommissionType())
                .eqIfPresent(SpuApplyDO::getSalesCount, reqVO.getSalesCount())
                .eqIfPresent(SpuApplyDO::getVirtualSalesCount, reqVO.getVirtualSalesCount())
                .eqIfPresent(SpuApplyDO::getBrowseCount, reqVO.getBrowseCount())
                .betweenIfPresent(SpuApplyDO::getCreateTime, reqVO.getCreateTime())
                .eqIfPresent(SpuApplyDO::getShopId, reqVO.getShopId())
                .eqIfPresent(SpuApplyDO::getMerchantId, reqVO.getMerchantId())
                .eqIfPresent(SpuApplyDO::getHidden, reqVO.getHidden())
                .eqIfPresent(SpuApplyDO::getPromotionFee, reqVO.getPromotionFee())
                .eqIfPresent(SpuApplyDO::getSpuPayType, reqVO.getSpuPayType())
                .eqIfPresent(SpuApplyDO::getHighPrecision, reqVO.getHighPrecision())
                .eqIfPresent(SpuApplyDO::getHighPrecisionPrice, reqVO.getHighPrecisionPrice())
                .eqIfPresent(SpuApplyDO::getApplyMemberUserId, reqVO.getApplyMemberUserId())
                .eqIfPresent(SpuApplyDO::getCheckSystemUserId, reqVO.getCheckSystemUserId())
                .betweenIfPresent(SpuApplyDO::getCheckTime, reqVO.getCheckTime())
                .eqIfPresent(SpuApplyDO::getCheckComment, reqVO.getCheckComment())
                .orderByDesc(SpuApplyDO::getId);

        if(reqVO.getCheckStatus() != null && reqVO.getCheckStatus().equals(1)){
            wrapper.ne(SpuApplyDO::getCheckStatus, 0);
        }else{
            wrapper.eq(SpuApplyDO::getCheckStatus, 0);
        }
        appendTabQuery(tabType, wrapper);

        return selectPage(reqVO, wrapper);
    }

    /**
     * 添加后台 Tab 选项的查询条件
     *
     * @param tabType 标签类型
     * @param query   查询条件
     */
    static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<SpuApplyDO> query) {
        // 出售中商品
        if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) {
            query.eqIfPresent(SpuApplyDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus());
        }
        // 仓储中商品
        if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) {
            query.eqIfPresent(SpuApplyDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus());
        }
        // 已售空商品
        if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) {
            query.eqIfPresent(SpuApplyDO::getStock, 0);
        }
        // 警戒库存
        if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) {
            query.le(SpuApplyDO::getStock, ProductConstants.ALERT_STOCK)
                    // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示
                    .notIn(SpuApplyDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
        }
        // 回收站
        if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) {
            query.eqIfPresent(SpuApplyDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
        }
    }

    @Select("select name from sale_shop where id=#{id}")
    String selectShopNameById(Long id);

    default Long selectCount(Integer checkStatus, ProductSpuPageReqVO pageVO){
        return selectCount(new LambdaQueryWrapperX<SpuApplyDO>()
                .eq(SpuApplyDO::getCheckStatus, checkStatus)
                .likeIfPresent(SpuApplyDO::getName, pageVO.getName())
                .eqIfPresent(SpuApplyDO::getShopId, pageVO.getShopId())
                .eqIfPresent(SpuApplyDO::getCategoryId, pageVO.getCategoryId())
                .eqIfPresent(SpuApplyDO::getMerchantId, pageVO.getMerchantId())
                .betweenIfPresent(SpuApplyDO::getCreateTime, pageVO.getCreateTime())
        );
    }

    default Long selectCount(SFunction<SpuApplyDO, ?> field, Object value, ProductSpuPageReqVO pageVO){
        return selectCount(new LambdaQueryWrapperX<SpuApplyDO>()
                .eq(field, value)
                .likeIfPresent(SpuApplyDO::getName, pageVO.getName())
                .eqIfPresent(SpuApplyDO::getShopId, pageVO.getShopId())
                .eqIfPresent(SpuApplyDO::getCategoryId, pageVO.getCategoryId())
                .eqIfPresent(SpuApplyDO::getMerchantId, pageVO.getMerchantId())
                .betweenIfPresent(SpuApplyDO::getCreateTime, pageVO.getCreateTime())
                .ne(SpuApplyDO::getCheckStatus, SpuApplyCheckStatusEnum.WAIT_CHECK.getStatus())
        );
    }

    default Long selectCount(ProductSpuPageReqVO pageVO) {
        LambdaQueryWrapperX<SpuApplyDO> queryWrapper = new LambdaQueryWrapperX<>();
        // 库存小于等于警戒库存
        queryWrapper
                .likeIfPresent(SpuApplyDO::getName, pageVO.getName())
                .eqIfPresent(SpuApplyDO::getShopId, pageVO.getShopId())
                .eqIfPresent(SpuApplyDO::getCategoryId, pageVO.getCategoryId())
                .eqIfPresent(SpuApplyDO::getMerchantId, pageVO.getMerchantId())
                .betweenIfPresent(SpuApplyDO::getCreateTime, pageVO.getCreateTime())
                .le(SpuApplyDO::getStock, ProductConstants.ALERT_STOCK)
                // 如果库存触发警戒库存且状态为回收站的话则不计入触发警戒库存的个数
                .notIn(SpuApplyDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus())
                .ne(SpuApplyDO::getCheckStatus, SpuApplyCheckStatusEnum.WAIT_CHECK.getStatus())
        ;
        return selectCount(queryWrapper);
    }
}