package com.fjhx.base;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fjhx.utils.PageUtil;
import org.springblade.core.secure.utils.AuthUtil;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;


public interface StorageBaseService<T> extends IService<T> {

    /**
     * 获取分页
     */
    default Page<T> createPage(Map<String, ?> condition) {
        return new Page<>(PageUtil.getCurrent(condition), PageUtil.getSize(condition));
    }

    /**
     * 获取分页
     */
    default Page<Map<String, Object>> createPageMap(Map<String, ?> condition) {
        return new Page<>(PageUtil.getCurrent(condition), PageUtil.getSize(condition));
    }

    /**
     * 执行分页查询
     *
     * @param condition    条件
     * @param queryWrapper wrapper
     * @return 分页后的对象
     */
    default Page<T> page(Map<String, ?> condition, Wrapper<T> queryWrapper) {
        Page<T> page = createPage(condition);
        return page(page, queryWrapper);
    }

    /**
     * 执行分页查询
     *
     * @param condition    条件
     * @param queryWrapper wrapper
     * @return 分页后的对象
     */
    default Page<Map<String, Object>> pageMaps(Map<String, ?> condition, Wrapper<T> queryWrapper) {
        Page<Map<String, Object>> page = createPageMap(condition);
        return pageMaps(page, queryWrapper);
    }

    /**
     * 获取添加过的某个字段的去重列表
     */
    default <S> List<S> getDistinctList(SFunction<T, S> column) {
        return list(Wrappers.<T>lambdaQuery().select(column))
                .stream().map(column).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }

    /**
     * 获取添加过的某个字段的去重列表
     */
    default <S> List<S> getDistinctList(Consumer<LambdaQueryWrapper<T>> consumer, SFunction<T, S> column) {
        return list(Wrappers.<T>lambdaQuery().func(consumer).select(column))
                .stream().map(column).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }

    /**
     * 条件查询
     */
    default List<T> list(SFunction<T, ?> column, Long val) {
        return lambdaQuery().eq(column, val).list();
    }

    default List<T> list(Consumer<LambdaQueryWrapper<T>> consumer) {
        return list(Wrappers.<T>lambdaQuery().func(consumer));
    }

    /**
     * 条件查询
     */
    default List<T> list(SFunction<T, ?> column, List<Long> val) {
        return lambdaQuery().in(column, val).list();
    }

    /**
     * 条件查询
     */
    default Map<String, Object> getMap(SFunction<T, ?> column, Object val) {
        return getMap(Wrappers.<T>lambdaQuery().eq(column, val).last("limit 1"));
    }

    /**
     * 条件查询
     */
    default T getOne(SFunction<T, ?> column, Object val) {
        return lambdaQuery().eq(column, val).last("limit 1").one();
    }

    /**
     * 条件查询
     */
    default Long count(SFunction<T, ?> column, Object val) {
        return lambdaQuery().eq(column, val).count();
    }

    /**
     * 条件查询
     */
    default Long count(Consumer<LambdaQueryWrapper<T>> consumer) {
        return count(Wrappers.<T>lambdaQuery().func(consumer));
    }

    /**
     * 按指定规则删除
     */
    default boolean remove(SFunction<T, ?> column, Long val) {
        return remove(Wrappers.<T>lambdaQuery().eq(column, val));
    }

    /**
     * 按指定规则删除
     */
    default boolean remove(SFunction<T, ?> column, List<Long> val) {
        return remove(Wrappers.<T>lambdaQuery().in(column, val));
    }

    /**
     * 条件查询
     */
    default void update(Consumer<LambdaUpdateWrapper<T>> consumer) {
        update(Wrappers.<T>lambdaUpdate().func(consumer));
    }

    @Override
    default boolean save(T entity) {
        setCreateInfo(entity);
        return IService.super.save(entity);
    }

    @Override
    default boolean saveBatch(Collection<T> entityList) {
        entityList.forEach(this::setCreateInfo);
        return IService.super.saveBatch(entityList);
    }

    @Override
    default boolean saveOrUpdateBatch(Collection<T> entityList) {
        entityList.forEach(item -> {
            if (item instanceof StorageBaseEntity) {
                if (ObjectUtil.isEmpty(((StorageBaseEntity) item).getId())) {
                    setCreateInfo(item);
                } else {
                    setUpdateInfo(item);
                }
            }
        });

        return IService.super.saveOrUpdateBatch(entityList);
    }

    @Override
    default boolean updateById(T entity) {
        setUpdateInfo(entity);
        return IService.super.updateById(entity);
    }

    @Override
    default boolean update(T entity, Wrapper<T> updateWrapper) {
        setUpdateInfo(entity);
        return IService.super.update(entity, updateWrapper);
    }

    @Override
    default boolean updateBatchById(Collection<T> entityList) {
        entityList.forEach(this::setUpdateInfo);
        return IService.super.updateBatchById(entityList);
    }

    @Override
    default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
        if (entity instanceof StorageBaseEntity) {
            if (ObjectUtil.isEmpty(((StorageBaseEntity) entity).getId())) {
                setCreateInfo(entity);
            } else {
                setUpdateInfo(entity);
            }
        }
        return IService.super.saveOrUpdate(entity, updateWrapper);
    }

    /**
     * 调新增方法时默认传入创建人、创建时间、租户id
     */
    default void setCreateInfo(T entity) {
        if (entity instanceof StorageBaseEntity) {
            Date date = new Date();
            Long userId = AuthUtil.getUserId();
            ((StorageBaseEntity) entity).setCreateUser(userId);
            ((StorageBaseEntity) entity).setCreateTime(date);
            ((StorageBaseEntity) entity).setUpdateUser(userId);
            ((StorageBaseEntity) entity).setUpdateTime(date);
        }
    }

    /**
     * 调编辑方法时默认传入更新人、更新时间
     */
    default void setUpdateInfo(T entity) {
        if (entity instanceof StorageBaseEntity) {
            ((StorageBaseEntity) entity).setCreateUser(null);
            ((StorageBaseEntity) entity).setCreateTime(null);
            ((StorageBaseEntity) entity).setUpdateUser(AuthUtil.getUserId());
            ((StorageBaseEntity) entity).setUpdateTime(new Date());
        }
    }

}
