package com.simuwang.base.common.support.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.simuwang.base.common.exception.APIException;
import com.simuwang.base.common.support.dos.BaseEntity;
import com.simuwang.base.common.support.MybatisPage;
import com.simuwang.base.common.support.command.BaseAddCmd;
import com.simuwang.base.common.support.command.BaseEditCmd;
import com.simuwang.base.common.support.command.BaseIdsCmd;
import com.simuwang.base.common.support.command.BaseIdStatusCmd;
import com.simuwang.base.common.support.query.PageQuery;
import com.simuwang.base.common.support.vo.BaseVO;

/**
 * @author wangzaijun
 * @date 2024/9/13 14:10
 * @description 数据库操作的基础service
 */
public interface IService<VO extends BaseVO, T extends BaseEntity<VO>> {
    String[] DEFAULT_COLUMNS = {"creatorid", "createtime"};

    String[] DEFAULT_SELECT_COLUMNS = extColumns(DEFAULT_COLUMNS, "isvalid", "remark", "updaterid", "updatetime");

    /**
     * 扩展查询的字段
     *
     * @param defaultColumns 默认的通用字段
     * @param ext            子类扩展的字段
     * @return /
     */
    static String[] extColumns(String[] defaultColumns, String... ext) {
        String[] newColumns = new String[defaultColumns.length + ext.length];
        System.arraycopy(defaultColumns, 0, newColumns, 0, defaultColumns.length);
        System.arraycopy(ext, 0, newColumns, defaultColumns.length, ext.length);
        return newColumns;
    }

    // ------------------------ 提供的可重现的查询扩展函数 start  ------------------------------------------

    /**
     * 获取查询列，默认只获取 {@see DEFAULT_SELECT_COLUMNS} 列字段
     *
     * @return /
     */
    default String[] selectColumns() {
        return DEFAULT_SELECT_COLUMNS;
    }

    /**
     * 包装查询条件，默认空实现
     *
     * @param wrapper 查询包装器
     * @param query   待处理条件
     */
    default <Q extends PageQuery> void wrapQuery(QueryWrapper<T> wrapper, Q query) {

    }

    /**
     * 分页结果转换
     *
     * @param page    分页参数
     * @param wrapper 查询条件
     * @return 分页结果
     */
    MybatisPage<VO> convertPage(Page<T> page, QueryWrapper<T> wrapper);

    // ------------------------ 提供的可重现的查询扩展函数 end  ------------------------------------------


    /**
     * 分页方法，仅支持单表分页
     *
     * @param query 分页查询对象
     * @return /
     */
    default <Q extends PageQuery> MybatisPage<VO> findPage(Q query) {
        Page<T> page = new Page<>(query.getCurrent(), query.getPageSize());
        page.setOrders(query.getOrderItems());
        QueryWrapper<T> wrapper = Wrappers.<T>query().select(this.selectColumns());
        this.wrapQuery(wrapper, query);
        if (StrUtil.isAllNotBlank(query.getBeginTime(), query.getEndTime())) {
            wrapper.between("createtime", query.getBeginTime(), query.getEndTime());
        }
        if (query.getOrderItems() != null) {
            query.getOrderItems().forEach(e -> wrapper.orderBy(true, e.isAsc(), e.getColumn()));
        } else {
            wrapper.orderByDesc("createtime");
        }
        return this.convertPage(page, wrapper);
    }

    /**
     * 新增记录的方法
     *
     * @param command 请求参数
     * @param <C>     泛型对象
     */
    default <C extends BaseAddCmd<T>> void insert(C command) {
        throw new APIException("方法insert未实现");
    }

    /**
     * 修改记录的方法
     *
     * @param command 请求参数
     * @param <C>     泛型对象
     */
    default <C extends BaseEditCmd<T>> void update(C command) {
        throw new APIException("方法update未实现");
    }

    /**
     * 根据id更新状态
     *
     * @param command /
     */
    default <C extends BaseIdStatusCmd> void updateStatus(C command) {
        throw new APIException("方法updateStatus未实现");
    }

    /**
     * 根据id删除记录
     *
     * @param command /
     */
    default <C extends BaseIdsCmd> void delete(C command) {
        throw new APIException("方法delete未实现");
    }
}
