
package com.lideeyunji.core.framework.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.lideeyunji.core.framework.mapper.LideeYunJiSqlMapper;
import com.lideeyunji.core.framework.service.IFrameSqlService;
import com.lideeyunji.tool.framework.common.constant.lideeYunJiBaseConstant;
import com.lideeyunji.tool.framework.yunji.adapter.IlideeYunjiAdapter;
import com.lideeyunji.tool.framework.yunji.enums.DefaultDbFieldEnum;
import com.lideeyunji.tool.framework.yunji.enums.LideeYunJiFieldTypeEnum;
import com.lideeyunji.tool.framework.yunji.utils.FuncBase;
import com.lideeyunji.tool.framework.sql.SqlHelper;
import com.lideeyunji.tool.framework.sql.build.buildmodel.wrapper.SqlInfoDeleteWrapper;
import com.lideeyunji.tool.framework.sql.build.buildmodel.wrapper.SqlInfoQueryWrapper;
import com.lideeyunji.tool.framework.sql.build.buildmodel.wrapper.SqlInfoUpdateWrapper;
import com.lideeyunji.tool.framework.sql.core.model.SqlFormatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 低代码平台
 * 该接口下所有业务不用租户过滤
 */

@Service
public class FrameSqlServiceImpl implements IFrameSqlService {

    @Autowired
    private LideeYunJiSqlMapper sqlMapper;

    @Autowired
    private IlideeYunjiAdapter lideeYunJiAdapter;

    //特殊处理
    String skipTablePre = "yunji_zexample_";

    @Override
    public void executeDDL(String ddlSql) {
        if (ddlSql.contains(skipTablePre)) {
            sqlMapper.executeDDL(lideeYunJiBaseConstant.DS_lideeyunji, ddlSql);
        } else {
            sqlMapper.executeDDL(lideeYunJiBaseConstant.DS_MASTER, ddlSql);
        }

    }

    //获取数据，不做租户等其他处理
    @Override
    public List<Map<String, Object>> getSimpleData(String sql) {
        Map<String, Object> dataMap = new HashMap<>();
        if (sql.contains(skipTablePre)) {
            return sqlMapper.selectData(lideeYunJiBaseConstant.DS_lideeyunji, sql, dataMap);
        } else {
            return sqlMapper.selectData(lideeYunJiBaseConstant.DS_MASTER, sql, dataMap);
        }

    }


    //添加参数到sqlformatmodel
    private Map<String, Object> getSqlFormatModelParam(SqlFormatModel sqlFormatModel, Map<String, Object> params) {
        Map<String, Object> dataMap = sqlFormatModel.getDataMap();
        if (FuncBase.isEmpty(dataMap)) {
            dataMap = new HashMap<>();
        }

        if (FuncBase.isEmpty(params)) {
            return dataMap;
        }

        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (dataMap.containsKey(key)) {
                continue;
            }
            // 如果map1中不存在该键，则添加
            dataMap.put(key, value);
        }
        return dataMap;
    }


    //查询数据相关
    //单个
    @Override
    public Map<String, Object> getDataOneByPlus(SqlInfoQueryWrapper.Wrapper wrapper) {
        return getDataOneByPlus(wrapper, null);
    }

    @Override
    public Map<String, Object> getDataOneByPlus(SqlInfoQueryWrapper.Wrapper wrapper, Map<String, Object> params) {
        SqlFormatModel sqlFormatModel = wrapper.buildSql();
        Map<String, Object> dataMap = getSqlFormatModelParam(sqlFormatModel, params);
        String sql = sqlFormatModel.getEwSql();
        List<Map<String, Object>> dataMapList = null;
        if (sql.contains(skipTablePre)) {
            dataMapList = sqlMapper.selectData(lideeYunJiBaseConstant.DS_lideeyunji, sql, dataMap);
        } else {
            dataMapList = sqlMapper.selectData(lideeYunJiBaseConstant.DS_MASTER, sql, dataMap);
        }
        return FuncBase.isEmpty(dataMapList) ? new HashMap<>() : dataMapList.get(0);
    }

    //多个
    @Override
    public List<Map<String, Object>> getDataListByPlus(SqlInfoQueryWrapper.Wrapper wrapper) {
        return getDataListByPlus(wrapper, null);
    }

    @Override
    public List<Map<String, Object>> getDataListByPlus(SqlInfoQueryWrapper.Wrapper wrapper, Map<String, Object> params) {
        SqlFormatModel sqlFormatModel = wrapper.buildSql();
        Map<String, Object> dataMap = getSqlFormatModelParam(sqlFormatModel, params);
        String sql = sqlFormatModel.getEwSql();
        List<Map<String, Object>> dataMapList = null;
        if (sql.contains(skipTablePre)) {
            dataMapList = sqlMapper.selectData(lideeYunJiBaseConstant.DS_lideeyunji, sql, dataMap);
        } else {
            dataMapList = sqlMapper.selectData(lideeYunJiBaseConstant.DS_MASTER, sql, dataMap);
        }
        return dataMapList;
    }

    @Override
    public List<Map<String, Object>> getDataListByPlus(String sql, Map<String, Object> params) {
        String publicSql = SqlHelper.getPublicSql(sql);
        SqlFormatModel sqlFormatModel = new SqlFormatModel();
        sqlFormatModel.setSql(publicSql);

        List<Map<String, Object>> dataMapList = null;
        if (sql.contains(skipTablePre)) {
            dataMapList = sqlMapper.selectData(lideeYunJiBaseConstant.DS_lideeyunji, sql, params);
        } else {
            dataMapList = sqlMapper.selectData(lideeYunJiBaseConstant.DS_MASTER, sql, params);
        }
        return dataMapList;
    }


    @Override
    public IPage<Map<String, Object>> getDataIPageByPlus(IPage page, SqlInfoQueryWrapper.Wrapper wrapper, Map<String, Object> params) {
        SqlFormatModel sqlFormatModel = wrapper.buildSql();
        Map<String, Object> dataMap = getSqlFormatModelParam(sqlFormatModel, params);
        IPage<Map<String, Object>> pages = null;
        String dataSourceType = wrapper.getDataSourceType();
        String sql = sqlFormatModel.getEwSql();
        if (FuncBase.isNotEmpty(dataSourceType)) {
            pages = sqlMapper.selectPageData(dataSourceType, page, sqlFormatModel.getEwSql(), dataMap);
        } else if (sql.contains(skipTablePre)) {
            pages = sqlMapper.selectPageData(lideeYunJiBaseConstant.DS_lideeyunji, page, sqlFormatModel.getEwSql(), dataMap);
        } else {
            pages = sqlMapper.selectPageData(lideeYunJiBaseConstant.DS_MASTER, page, sqlFormatModel.getEwSql(), dataMap);
        }
        return pages;
    }

    @Override
    public IPage<Map<String, Object>> getDataIPageByPlus(IPage page, SqlInfoQueryWrapper.Wrapper wrapper) {
        return getDataIPageByPlus(page, wrapper, null);
    }

    //修改数据相关
    @Override
    public void updateDataByPlus(SqlInfoUpdateWrapper.Wrapper wrapper) {
        SqlFormatModel sqlFormatModel = wrapper.buildSql();
        String sql = sqlFormatModel.getEwSql();

        if (sql.contains(skipTablePre)) {
            sqlMapper.updateData(lideeYunJiBaseConstant.DS_lideeyunji,sql, sqlFormatModel.getDataMap());
        } else {
            sqlMapper.updateData(lideeYunJiBaseConstant.DS_MASTER,sql, sqlFormatModel.getDataMap());
        }
    }

    //新增数据相关
    @Override
    public void insertDataByPlus(String tableName, Map<String, Object> addDataMap) {
        this.insertDataByPlus(tableName, addDataMap,null);
    }

    @Override
    public void insertDataListByPlus(String tableName,
                                     Map<String,String> fieldNameTypeMap,
                                     List<Map<String, Object>> dataMapList){
        //处理默认值 id,tenant_id,create_time,create_user,create_dept
        fieldNameTypeMap.put(DefaultDbFieldEnum.ID.getFieldCode(),"BIGINT");
        fieldNameTypeMap.put(DefaultDbFieldEnum.TENANT_ID.getFieldCode(),"VARCHAR");
        fieldNameTypeMap.put(DefaultDbFieldEnum.CREATE_TIME.getFieldCode(),"TIMESTAMP");
        fieldNameTypeMap.put(DefaultDbFieldEnum.CREATE_USER.getFieldCode(),"BIGINT");
        fieldNameTypeMap.put(DefaultDbFieldEnum.CREATE_DEPT.getFieldCode(),"BIGINT");
        fieldNameTypeMap.put(DefaultDbFieldEnum.IS_DELETED.getFieldCode(),"INTEGER");

        //赋予默认值
        for(Map<String, Object> dataMap:dataMapList){
            if(!dataMap.containsKey(DefaultDbFieldEnum.ID.getFieldCode())){
                dataMap.put(DefaultDbFieldEnum.ID.getFieldCode(), IdWorker.getId());
            }
            if(!dataMap.containsKey(DefaultDbFieldEnum.TENANT_ID.getFieldCode())){
                dataMap.put(DefaultDbFieldEnum.TENANT_ID.getFieldCode(), lideeYunJiAdapter.getTenantId());
            }
            if(!dataMap.containsKey(DefaultDbFieldEnum.CREATE_TIME.getFieldCode())){
                dataMap.put(DefaultDbFieldEnum.CREATE_TIME.getFieldCode(), DateUtil.date());
            }
            if(!dataMap.containsKey(DefaultDbFieldEnum.CREATE_USER.getFieldCode())){
                dataMap.put(DefaultDbFieldEnum.CREATE_USER.getFieldCode(), lideeYunJiAdapter.getOnlineUserId());
            }
            if(!dataMap.containsKey(DefaultDbFieldEnum.CREATE_DEPT.getFieldCode())){
                dataMap.put(DefaultDbFieldEnum.CREATE_DEPT.getFieldCode(), lideeYunJiAdapter.getOnlineUserDeptId());
            }
            if(!dataMap.containsKey(DefaultDbFieldEnum.IS_DELETED.getFieldCode())){
                dataMap.put(DefaultDbFieldEnum.IS_DELETED.getFieldCode(), 0);
            }
        }
        // 每1000条数据执行一次批量插入
        int batchSize = 1000;
        for (int i = 0; i < dataMapList.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, dataMapList.size());
            List<Map<String, Object>> subList = dataMapList.subList(i, endIndex);
            sqlMapper.insertDataList(lideeYunJiBaseConstant.DS_MASTER, tableName, fieldNameTypeMap, subList);
        }
    }

    @Override
    public void insertDataByPlus(String tableName, Map<String, Object> addDataMap,Map<String, LideeYunJiFieldTypeEnum> fieldTypeEnumMap) {
        SqlFormatModel sqlFormatModel = SqlHelper.getInsertWrapper()
                .setTableName(tableName)
                .setMap(addDataMap)
                .setFieldType(fieldTypeEnumMap)
                .buildSql();
        String sql = sqlFormatModel.getEwSql();
        if (sql.contains(skipTablePre)) {
            sqlMapper.insertData(lideeYunJiBaseConstant.DS_lideeyunji,sql, sqlFormatModel.getDataMap());
        } else {
            sqlMapper.insertData(lideeYunJiBaseConstant.DS_MASTER,sql, sqlFormatModel.getDataMap());
        }
    }


    //真实-删除数据
    @Override
    public void delRealDataByPlus(SqlInfoDeleteWrapper.Wrapper wrapper) {
        SqlFormatModel sqlFormatModel = wrapper.buildSql();
        String sql = sqlFormatModel.getEwSql();
        if (sql.contains(skipTablePre)) {
            sqlMapper.deleteData(lideeYunJiBaseConstant.DS_lideeyunji,sqlFormatModel.getEwSql(), sqlFormatModel.getDataMap());
        } else {
            sqlMapper.deleteData(lideeYunJiBaseConstant.DS_MASTER,sqlFormatModel.getEwSql(), sqlFormatModel.getDataMap());
        }


    }

    //逻辑-删除数据
    @Override
    public void delDataByPlus(SqlInfoUpdateWrapper.Wrapper wrapper) {
        wrapper.setColumn("is_deleted", -1);
        SqlFormatModel sqlFormatModel = wrapper.buildSql();

        String sql = sqlFormatModel.getEwSql();
        if (sql.contains(skipTablePre)) {
            sqlMapper.updateData(lideeYunJiBaseConstant.DS_lideeyunji,sqlFormatModel.getEwSql(), sqlFormatModel.getDataMap());
        } else {
            sqlMapper.updateData(lideeYunJiBaseConstant.DS_MASTER,sqlFormatModel.getEwSql(), sqlFormatModel.getDataMap());
        }
    }

    //----------------------------------------------------------
    //获取表数据
    @Override
    public List<Map<String, Object>> getTableDataList(String tableName) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .build();
        List<Map<String, Object>> resultList = this.getDataListByPlus(wrapper);
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getTableDataList(String tableName, List<String> fieldList) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .select(fieldList, true)
                .build();
        return this.getDataListByPlus(wrapper);
    }

    //根据Id获取数据
    @Override
    public Map<String, Object> getTableDataById(String tableName, Long id) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq("id", id);
                })
                .build();
        return this.getDataOneByPlus(wrapper);
    }

    @Override
    public Map<String, Object> getTableDataById(String tableName, Long id, List<String> fieldList) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .select(fieldList, true)
                .setWhere(where -> {
                    where.eq("id", id);
                })
                .build();
        return this.getDataOneByPlus(wrapper);
    }

    //自定义根据某一个字段查询--单条
    @Override
    public Map<String, Object> getDataOneByField(String tableName, String whereFieldName, Object whereFieldValue) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                })
                .build();

        return this.getDataOneByPlus(wrapper);
    }

    @Override
    public Map<String, Object> getDataOneByField(String tableName, String whereFieldName, Object whereFieldValue, List<String> fieldList) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .select(fieldList, true)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                })
                .build();
        return this.getDataOneByPlus(wrapper);
    }

    //自定义根据某一个字段查询--多条
    @Override
    public List<Map<String, Object>> getDataListByField(String tableName, String whereFieldName, Object whereFieldValue) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                })
                .build();
        return this.getDataListByPlus(wrapper);
    }

    @Override
    public List<Map<String, Object>> getDataListByField(String tableName, String whereFieldName, Object whereFieldValue, List<String> fieldList) {
        SqlInfoQueryWrapper.Wrapper wrapper = SqlHelper.getQueryWrapper()
                .setTableName(tableName)
                .select(fieldList, true)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                })
                .build();

        return this.getDataListByPlus(wrapper);
    }

    //公共修改
    @Override
    public void baseUpdateDataById(String tableName, Map<String, Object> dataMap, Long id) {
        SqlInfoUpdateWrapper.Wrapper wrapper = SqlHelper.getUpdateWrapper()
                .setTableName(tableName)
                .setMap(dataMap)
                .setWhere(where -> {
                    where.eq("id", id);
                }).build();
        this.updateDataByPlus(wrapper);
    }

    public void baseUpdateDataByField(String tableName, Map<String, Object> dataMap, String whereFieldName, Object whereFieldValue) {
        SqlInfoUpdateWrapper.Wrapper wrapper = SqlHelper.getUpdateWrapper()
                .setTableName(tableName)
                .setMap(dataMap)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                }).build();
        this.updateDataByPlus(wrapper);
    }

    //公共删除-逻辑
    @Override
    public void baseDelDataById(String tableName, Long id) {
        SqlInfoUpdateWrapper.Wrapper wrapper = SqlHelper.getUpdateWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq("id", id);
                });
        this.delDataByPlus(wrapper);
    }

    @Override
    public void baseDelDataByField(String tableName, String whereFieldName, Object whereFieldValue) {
        SqlInfoUpdateWrapper.Wrapper wrapper = SqlHelper.getUpdateWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                });
        this.delDataByPlus(wrapper);
    }

    //公共删除-真实
    @Override
    public void baseDelRealData(String tableName, Long id) {
        SqlInfoDeleteWrapper.Wrapper wrapper = SqlHelper.getDeleteWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq("id", id);
                }).build();
        this.delRealDataByPlus(wrapper);
    }

    @Override
    public void baseDelRealData(String tableName, List<Long> idList) {
        SqlInfoDeleteWrapper.Wrapper wrapper = SqlHelper.getDeleteWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.in("id", idList);
                }).build();
        this.delRealDataByPlus(wrapper);
    }

    @Override
    public void baseDelRealDataByField(String tableName, String whereFieldName, Object whereFieldValue) {
        SqlInfoDeleteWrapper.Wrapper wrapper = SqlHelper.getDeleteWrapper()
                .setTableName(tableName)
                .setWhere(where -> {
                    where.eq(whereFieldName, whereFieldValue);
                }).build();
        this.delRealDataByPlus(wrapper);
    }

}
