package cc.smtweb.system.bpm.web.design.form;

import cc.smtweb.framework.core.annotation.SwBody;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.cache.ModelTableCache;
import cc.smtweb.framework.core.db.vo.ModelField;
import cc.smtweb.framework.core.db.vo.ModelTable;
import cc.smtweb.framework.core.mvc.service.AbstractCompService;
import cc.smtweb.framework.core.mvc.service.AbstractHandler;
import cc.smtweb.framework.core.mvc.service.DefaultListHandler;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.SqlUtil;
import cc.smtweb.system.bpm.util.CodeGenerator;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefine;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefineCache;
import org.apache.commons.lang3.StringUtils;

import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Created by Akmm at 2022/3/22 9:12
 */
@SwService
public class ModelFormService extends AbstractCompService {
    private final static String TYPE_CODE = "type_code";

    @Override
    protected AbstractHandler createHandler(String type) {
        switch (type) {
            case TYPE_LOAD:
                return new ModelFormLoadHandler();
            case TYPE_SAVE:
                return new ModelFormSaveHandler();
            case TYPE_DEL:
                return new ModelFormDelHandler();
            case TYPE_LIST:
                return new DefaultListHandler<ModelForm>(ModelForm.ENTITY_NAME);
            case TYPE_CODE:
                return new CodeBuildHandler();
        }
        return null;
    }

    //保存数据集
    public R saveDataset(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE);
            return handler.saveDataset();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //加载数据集
    public R loadDataset(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD);
            return handler.loadDataset();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //保存页面模型
    public R saveModel(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE);
            return handler.saveModel();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //根据模板保存页面定义
    public R saveModelByTmpl(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormSaveHandler handler = (ModelFormSaveHandler) getHandler(params, us, TYPE_SAVE);
            return handler.saveModelByTmpl();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //加载页面模型
    public R loadModel(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD);
            return handler.loadModel();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //加载页面js方法
    public R loadJsFuncs(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD);
            return handler.loadJsFuncs();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //加载引擎用页面模型
    public R model(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD);
            return handler.loadForm();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //获取页面使用的控件的filter信息
    public R loadWidgetFilter(@SwBody SwMap params, UserSession us) {
        try {
            ModelFormLoadHandler handler = (ModelFormLoadHandler) getHandler(params, us, TYPE_LOAD);
            return handler.loadWidgetFilter();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //获取自定义sql的字段信息，去库里查
    public R loadSqlFields(@SwBody SwMap params, UserSession us) {
        try {
            String sql = params.readString("sql");
            if (StringUtils.isEmpty(sql)) return R.error("没有传入的sql！");
            long masterTable = params.readLong("masterTable");
            if (masterTable <= 0L) return R.error("没有传入的masterTable！");
            ModelTable table = ModelTableCache.getInstance().get(masterTable);
            if (table == null) return R.error("没有找到表定义信息(masterTable=" + masterTable + ")！");

            sql = sql.trim().toLowerCase();
            if (!sql.startsWith("select")) return R.error("非查询类sql，禁止执行！");
            if (sql.contains(";")) return R.error("sql内禁止出现分号！");
            sql = SqlUtil.replaceTable(sql);
            List<SwMap> ret = DbEngine.getInstance().query(sql + " where 1=0", rs -> {
                List<SwMap> fields = new ArrayList<>();
                ResultSetMetaData metaData = rs.getMetaData();

                for (int i = 1, count = metaData.getColumnCount(); i <= count; i++) {
                    SwMap col = new SwMap(2);
                    final String colName = metaData.getColumnLabel(i).toLowerCase();
                    col.put("name", colName);
                    ModelField field = table.findField(colName);
                    if (field != null) {
                        ModelFormHelper.buildFieldInfo(table, field, col);
                    } else {
                        SwEnum.DataTypeBean dtb = SwEnum.DataType.getBySqlType(metaData.getColumnType(i), metaData.getPrecision(i), metaData.getScale(i));
                        col.put("dataType", dtb.value);
                        col.put("editor", dtb.editor);
                    }
                    fields.add(col);
                }
                return fields;
            });
            return R.success(ret);
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    public R loadFieldCfg(@SwBody SwMap params, UserSession us) {
        long tableId = params.readLong("tableId");
        if (tableId <= 0L) return R.error("没有传入的Table！");
        ModelTable table = ModelTableCache.getInstance().get(tableId);
        if (table == null) return R.error("没有找到表定义信息(table=" + tableId + ")！");

        List<SwMap> ret = new ArrayList<>();
        for (ModelField field : table.getFields()) {
            SwMap col = new SwMap(2);
            ModelFormHelper.buildFieldInfo(table, field, col);
            ret.add(col);
        }
        return R.success(ret);
    }

    //加载模板定义
    public R loadTmpls(@SwBody SwMap params, UserSession us) {
        return R.success(CodeGenerator.getInstance().getModelTemplates());
    }

    //生成java代码
    public R buildJavaCode(@SwBody SwMap params, UserSession us) {
        try {
            CodeBuildHandler handler = (CodeBuildHandler) getHandler(params, us, TYPE_CODE);
            return handler.buildJavaCode();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }

    //生成js代码
    public R buildJsCode(@SwBody SwMap params, UserSession us) {
        try {
            CodeBuildHandler handler = (CodeBuildHandler) getHandler(params, us, TYPE_CODE);
            return handler.buildJsCode();
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }
    // 获取数据权限类型
    public R loadDataRightType(@SwBody SwMap params, UserSession us) {
        try {
            long prj_id = params.readLong("prj_id");
            List<SwMap> rtData = new ArrayList<>();
            if(prj_id<=0){
                return R.success(rtData);
            }
            // 查项目所依赖的项目
            Set<Long> ids =  ModelProjectCache.getInstance().getDependsPrjIds(prj_id);
            if(CommUtil.isEmpty(ids)){
              return R.success(rtData);
            }
            ids.forEach(id -> {
                // 取数据权限定义
                Set<DataRightDefine> dfs = DataRightDefineCache.getInstance().getByMp(id.toString());
                if(!CommUtil.isEmpty(dfs)){
                    dfs.forEach(bean -> {
                        SwMap map = new SwMap();
                        map.put("value",bean.getId());
                        map.put("label",bean.getName());
                        map.put("bean",bean);
                        rtData.add(map);
                    });
                }
            });
            return R.success(rtData);
        } catch (Exception e) {
            return R.error("操作失败！", e);
        }
    }
}
