package com.kingdee.eas.custom.dataconfig.utils.service;

import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.bsf.service.app.IHRMsfService;
import com.kingdee.bos.metadata.entity.EntityObjectInfo;
import com.kingdee.bos.metadata.entity.FilterInfo;
import com.kingdee.bos.sql.ParserException;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.dataconfig.utils.SqlUtils;
import com.kingdee.eas.custom.entryconfig.*;
import com.kingdee.eas.custom.entryconfig.enumlist.RelationshipEnum;

import java.util.Map;

/**
 * SQL生成服务类
 * 实现IHRMsfService接口，用于处理SQL查询语句的构建逻辑
 */
public class GetSqlService implements IHRMsfService {
    /**
     * 处理方法，根据输入参数构建SQL查询语句
     *
     * @param context 上下文对象，用于获取系统环境信息和服务实例
     * @param map     输入参数集合，包含构建SQL所需的参数
     * @return 构建完成的SQL语句字符串（以StringBuilder形式返回）
     * @throws EASBizException EAS业务异常，处理业务逻辑错误
     * @throws BOSException    BOS框架异常，处理框架层面错误
     */
    @Override
    public Object process(Context context, Map map) throws EASBizException, BOSException {
        // 从输入参数中获取"number"键对应的值，该值为数据配置的编号
        Object o = map.get("number");
        // 检查number参数是否为空
        if (o == null) {
            // 若为空则抛出运行时异常，提示number参数不可为空
            throw new RuntimeException("number参数不能为空！");
        }
        // 将number参数转换为字符串类型
        String number = o.toString();
        // 实例化SQL工具类，用于处理SQL构建相关的工具方法
        SqlUtils sqlUtils = new SqlUtils();
        // 根据number编号查询对应的数据配置信息
        // 此处SQL查询条件为number字段等于输入的编号，查询数据配置主信息及关联的条目信息
        DataConfigInfo dataConfigInfo = DataConfigFactory.getLocalInstance(context)
                .getDataConfigInfo("select *,entrys.* where number  = '" + number + "' order by entrys.seq ");
        // 获取数据配置中包含的实体条目集合（如关联的表/实体信息）
        DataConfigEntryCollection entrys = dataConfigInfo.getEntrys();

        if(entrys.size()<1){
            return "";
        }

        // 获取数据配置中包含的字段条目集合（如需要查询的字段信息）
        DataConfigFieldEntryCollection fieldEntry = dataConfigInfo.getFieldEntry();

        // 创建StringBuilder对象用于拼接SQL语句
        StringBuilder sql = new StringBuilder();
        // 拼接SQL的SELECT部分，{{filed}}为字段占位符，后续需替换为实际字段
        sql.append("select ").append("\n").append("{{filed}} ").append("\n").append("from").append("\n");

        // 获取当前索引对应的实体条目信息
        DataConfigEntryInfo dataConfigEntryInfo = entrys.get(0);
        // 获取当前实体的全路径（如实体的完整类名或唯一标识）
        String entryFull = dataConfigEntryInfo.getEntryFull();
        // 获取当前实体在SQL中的别名
        String alias = dataConfigEntryInfo.getAlias();
        // 根据实体全路径和上下文获取实体的元信息（包含实体结构、字段等信息）
        EntityObjectInfo entryInfo = sqlUtils.getEntryInfo(entryFull, context);
        // 调用工具类方法，向SQL中拼接当前实体的表名、别名等信息（作为主表，isMain参数为true）
        sqlUtils.getSql(sql, entryInfo, alias, context, true, null);

        // 循环处理实体条目集合，构建FROM及关联部分
        for (int i = 1; i < entrys.size(); i++) {
            // 获取下一个实体条目信息
            DataConfigEntryInfo dataConfigEntryInfo1 = entrys.get(i);
            // 获取下一个实体的全路径
            String entryFull1 = dataConfigEntryInfo1.getEntryFull();
            // 获取下一个实体在SQL中的别名
            String alias1 = dataConfigEntryInfo1.getAlias();
            // 根据下一个实体的全路径和上下文获取其元信息
            EntityObjectInfo entryInfo1 = sqlUtils.getEntryInfo(entryFull1, context);
            // 获取当前实体与下一个实体的关联关系（如内连接、左连接等）
            RelationshipEnum relationship = dataConfigEntryInfo1.getRelationship();
            // 获取当前实体与下一个实体的关联字段（用于拼接ON条件）
            String relationFeild = dataConfigEntryInfo1.getRelationFeild();
            // 向SQL中拼接关联关键字（如INNER JOIN、LEFT JOIN等）
            sql.append(relationship.getValue()).append("\t");
            // 调用工具类方法，向SQL中拼接下一个实体的表名、别名及关联条件（作为关联表，isMain参数为false）
            try {
                FilterInfo filter = new FilterInfo(relationFeild);
                sqlUtils.getSql(sql, entryInfo1, alias1, context, false, filter.toSql());
            } catch (ParserException e) {
                throw new RuntimeException(e);
            }
        }
        // 返回构建完成的SQL语句
        return sql;
    }
}