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.AttributeAssignBuilder;
import com.fjhx.utils.PageUtil;
import org.springblade.core.secure.utils.AuthUtil;

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


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


    default <V> AttributeAssignBuilder<T, V> attributeAssignBuilder(List<V> list) {
        return AttributeAssignBuilder.init(this, list);
    }

    default <V> void attributeAssign(List<V> list, Function<V, Long> getIdFun, BiConsumer<V, T> setAttributeFun) {
        attributeAssignBuilder(list).assignFun(getIdFun, setAttributeFun).build();
    }

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

    /**
     * 获取分页
     */
    default Page<Map<String, Object>> createPageMap(Map<String, ?> condition) {
        return PageUtil.createPageMap(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 List<?> getDistinctList(SFunction<T, ?> column) {
        return list(Wrappers.<T>lambdaQuery().select(column))
                .stream().map(column).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }

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

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

    /**
     * 条件查询
     */
    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 Map<String, Object> getMap(Consumer<LambdaQueryWrapper<T>> consumer) {
        return getMap(Wrappers.<T>lambdaQuery().func(consumer).last("limit 1"));
    }

    default T getOne(Consumer<LambdaQueryWrapper<T>> consumer) {
        return getOne(Wrappers.<T>lambdaQuery().func(consumer).last("limit 1"));
    }

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

    default List<Map<String, Object>> listMaps(Consumer<LambdaQueryWrapper<T>> consumer) {
        return listMaps(Wrappers.<T>lambdaQuery().func(consumer));
    }

    default <V> List<V> listObj(SFunction<T, V> mapper, Consumer<LambdaQueryWrapper<T>> consumer) {
        return list(Wrappers.<T>lambdaQuery().select(mapper).func(consumer))
                .stream().map(mapper).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    }

    default <K, V> Map<K, V> getKV(SFunction<T, K> kFun, SFunction<T, V> vFun, Consumer<LambdaQueryWrapper<T>> consumer) {
        List<T> list = list(Wrappers.<T>lambdaQuery().select(kFun, vFun).func(consumer));
        return list.stream().collect(Collectors.toMap(kFun, vFun, (v1, v2) -> v2));
    }

    default <K> Map<K, T> getKEntity(SFunction<T, K> kFun, Consumer<LambdaQueryWrapper<T>> consumer) {
        return list(Wrappers.<T>lambdaQuery().func(consumer))
                .stream().collect(Collectors.toMap(kFun, item -> item, (v1, v2) -> v2));
    }

    default <K> Map<K, List<T>> getKGroup(SFunction<T, K> kFun, Consumer<LambdaQueryWrapper<T>> consumer) {
        return list(Wrappers.<T>lambdaQuery().func(consumer))
                .stream().collect(Collectors.groupingBy(kFun));
    }

    default boolean update(Consumer<LambdaUpdateWrapper<T>> consumer) {
        return update(Wrappers.<T>lambdaUpdate().func(consumer));
    }

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

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

    @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 BaseEntity) {
                if (ObjectUtil.isEmpty(((BaseEntity) 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 BaseEntity) {
            if (ObjectUtil.isEmpty(((BaseEntity) entity).getId())) {
                setCreateInfo(entity);
            } else {
                setUpdateInfo(entity);
            }
        }
        return IService.super.saveOrUpdate(entity, updateWrapper);
    }

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

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

}
