package com.boman.web.core.service.select;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boman.common.redis.RedisKey;
import com.boman.domain.GenTable;
import com.boman.web.core.mapper.StandardlyMapper;
import com.boman.web.core.service.TableServiceCmdService;
import com.boman.web.core.utils.ColumnUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.boman.common.core.utils.obj.ObjectUtils.isEmpty;
import static com.boman.common.core.utils.obj.ObjectUtils.requireNonNull;

/**
 * @author shiqian
 * @date 2021年03月29日 10:22
 **/
@Service
public class BaseSelectServiceImpl implements IBaseSelectService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BaseSelectServiceImpl.class);

    @Autowired
    private StandardlyMapper mapper;
    @Autowired
    private TableServiceCmdService cmdService;


    /**
     * 功能描述: 根据条件查询
     *
     * @param tableName     tableName
     * @param condition     原始查询条件
     * @param packCondition 封装的查询条件
     * @param showData      前台需要查询的列
     * @param orderBy       orderBy
     * @param limit         分页
     * @param offset        分页
     * @return java.util.List<com.alibaba.fastjson.JSONObject>
     */
    @Override
    public List<JSONObject> selectByCondition(String tableName, JSONObject condition
            , JSONObject packCondition, JSONArray showData, String orderBy, Integer limit, Integer offset) {
        requireNonNull(tableName, "表名为空");
        requireNonNull(showData, "表: [" + tableName + "] , 过滤了可展示字段，一个展示字段都没有，还查个鬼啊");
        requireNonNull(orderBy);
        return mapper.selectByCondition(tableName, condition, packCondition, showData, orderBy, limit, offset);
    }

    /**
     * 功能描述: 根据tableName和map(属性名和属性值)进行查查
     *
     * @param tableName tableName
     * @param param     属性名和属性值
     * @return java.util.List<com.alibaba.fastjson.JSONObject>
     */
    @Override
    public List<JSONObject> getByMap(String tableName, JSONObject param) {
        requireNonNull(tableName, "表名为空");

        // 判断condition中列是否都在此table中
        GenTable gent = cmdService.getTableFromRedisByTableName(RedisKey.TABLE_INFO, tableName);
        ColumnUtils.checkColumn(param, gent.getColumns());
        return mapper.getByMap(tableName, param, false);
    }


    /**
     * 功能描述: 根据tableName和map(属性名和属性值)进行查查
     *
     * @param tableName tableName
     * @param param     属性名和属性值
     * @return com.alibaba.fastjson.JSONObject
     */
    @Override
    public JSONObject getOneByMap(String tableName, JSONObject param) {
        requireNonNull(tableName, "表名为空");

        // 判断condition中列是否都在此table中
        GenTable gent = cmdService.getTableFromRedisByTableName(RedisKey.TABLE_INFO, tableName);
        ColumnUtils.checkColumn(param, gent.getColumns());
        List<JSONObject> result = mapper.getByMap(tableName, param, true);
        return isEmpty(result) ? null : result.get(0);
    }

    /**
     * 功能描述: 根据条件查询
     *
     * @param tableName     tableName
     * @param condition     原始查询条件
     * @param packCondition 封装的查询条件
     * @return int
     */
    @Override
    public int countByCondition(String tableName, JSONObject condition, JSONObject packCondition) {
        requireNonNull(tableName, "表名为空");
        return mapper.countByCondition(tableName, condition, packCondition);
    }

    /**
     * 功能描述: 根据id查所有，不支持自定义查询列
     *
     * @param tableName 表名
     * @param pkName    主键名称
     * @param id        主键值
     * @return com.alibaba.fastjson.JSONObject
     */
    @Override
    public JSONObject selectById(String tableName, String pkName, Long id) {
        requireNonNull(tableName, "表名为空");
        requireNonNull(pkName, "主键名称为空");;
        requireNonNull(id);
        return mapper.selectById(tableName, pkName, id);
    }

    /**
     * 功能描述: 根据id查所有，不支持自定义查询列
     *
     * @param tableName 表名
     * @param pkName    主键名称
     * @param idList    主键值
     * @param showData  需要展示的列
     * @return com.alibaba.fastjson.JSONObject
     */
    @Override
    public List<JSONObject> selectByIdList(String tableName, String pkName, List<Long> idList, List<String> showData) {
        requireNonNull(tableName, "表名为空");
        requireNonNull(pkName, "主键名称为空");;
        requireNonNull(idList);

        return mapper.selectByIdList(tableName, pkName, idList, showData);
    }
}
