package com.seeyon.apps.src_powerfeeinvoice.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.aicloud.common.JsonUtils;
import com.seeyon.apps.src_powerfeeinvoice.config.HttpFormRestApiConfig;
import com.seeyon.cap4.form.api.FormApi4Cap4;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormBindAuthBean;
import com.seeyon.cap4.form.bean.FormBindBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.bean.FormTableBean;
import com.seeyon.client.CTPRestClient;
import com.seeyon.client.CTPServiceClientManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.util.JDBCAgent;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import www.seeyon.com.utils.StringUtil;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

public class FormDataOperator {

    public void updateMasterForm(String formNo, List<FormUpdateField> updateFieldVos, List<FormWhereCondition> conditionVos) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
        if (updateFieldVos == null) {
            throw new IllegalArgumentException("要修改的字段为空");
        }
        for (FormUpdateField fieldVo : updateFieldVos) {
            FormFieldBean bean = masterTableBean.getFieldBeanByDisplay(fieldVo.getDisplay());
            if (bean == null) {
                continue;
            }
            if(bean.getInputType().equals("image") || bean.getInputType().equals("attachment")) {

            }
                fieldVo.fieldName(bean.getColumnName());
        }
        List<FormUpdateField> updateFields = updateFieldVos.stream().filter(u -> u.getFieldName() != null).collect(Collectors.toList());
        for (FormWhereCondition conditionVo : conditionVos) {
            FormFieldBean bean = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay());
            if (bean == null) {
                if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) {
                    conditionVo.setFieldName(conditionVo.getDisplay());
                }
                continue;
            }
            conditionVo.setFieldName(bean.getColumnName());
        }
        List<FormWhereCondition> conditions = conditionVos.stream().filter(c -> c.getFieldName() != null).collect(Collectors.toList());
        Map<String, Object> map = generateSql(updateFields, masterTableBean.getTableName(), conditions);
        JDBCAgent agent = new JDBCAgent();
        try {
            agent.execute((String) map.get("sql"), (List<Object>) map.get("params"));
            return;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            agent.close();
        }
    }

    public Long countCondition(String formNo,List<FormWhereCondition> conditionVos) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
        String tableName = masterTableBean.getTableName();
        for (FormWhereCondition conditionVo : conditionVos) {
            FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay());
            if (fieldBeanByDisplay == null) {
                continue;
            }
            conditionVo.setFieldName(fieldBeanByDisplay.getColumnName());
        }

        Map<String, Object> generateSql = generateSql(conditionVos, tableName);
        String sql = (String) generateSql.get("sql");
        List<Object> params = (List<Object>) generateSql.get("params");
        JDBCAgent jdbcAgent = new JDBCAgent();
        try {
            jdbcAgent.execute(sql, params);
            return (Long) jdbcAgent.resultSetToMap().get("countsize");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            jdbcAgent.close();
        }
        return null;
    }

    public void refreshForm(String id, String formNo, String formLoginName, HttpFormRestApiConfig config) throws BusinessException, IOException {
        FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
        List<Object> dataList = new ArrayList<>();
        Map<String,Object> temp1 = new HashMap<>();
        Map<String,Object> temp2 = new HashMap<>();
        temp1.put("masterTable",temp2);
        temp2.put("name",masterTableBean.getTableName());
        Map<String, Object> recordMap = new HashMap<>(3); // 容量=3 (2/0.75≈2.67)
        recordMap.put("id", id);
        recordMap.put("fields", new ArrayList<>());
        temp2.put("record", recordMap);
        temp2.put("changedFields",new ArrayList<>());
        dataList.add(temp1);
        String token = getToken(config.getTokenUrl(),config.getRestUserName(),config.getRestPwd(),formLoginName);
        Map beanMap = new HashMap();
        beanMap.put("formCode", formNo);
        beanMap.put("loginName", formLoginName);
        beanMap.put("doTrigger", "true");
        beanMap.put("rightId", config.getRightId());
        beanMap.put("dataList",dataList);
        Map<String, String> header = new HashMap<>();
        header.put("token", token);
        String url = config.getBaseUrl() + "/seeyon/rest/cap4/form/soap/batch-update";
        String response = HttpClient.httpPostRaw(url, JsonUtils.toJSONString(beanMap), header, "UTF-8");
        System.out.println(response);
    }
    private String getToken(String oatokenurl,String restName,String restPassword,String loginName) throws FileNotFoundException, IOException {
        String address = oatokenurl + restName + "/" + restPassword;
        if(StringUtil.isNotEmpty(loginName)){
            address = address +"?loginName="+loginName;
        }
        DefaultHttpClient client = new DefaultHttpClient();
        String result = "";
        HttpGet get = new HttpGet(address);
        // 添加 Headers 信息
        get.addHeader(new BasicHeader("Accept", "application/json"));
        try {
            HttpResponse res = client.execute(get);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                result = EntityUtils.toString(res.getEntity());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        String token = "";
        if(result.contains("{")) {
            JSONObject jsObj = JSONObject.parseObject(result);
            token = jsObj.get("id").toString();
        }else {
            token = result;
        }
        return token;
    }

    public List<FormColumn> queryFormDataCondition(String formNo, List<String> queryColumnVos, List<FormWhereCondition> conditionVos) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        List<String> queryColumns = new ArrayList<>();
        FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
        String tableName = masterTableBean.getTableName();
        Map<String, FormFieldBean> fieldMap4Name = masterTableBean.getFieldMap4Name();
        if (queryColumnVos != null) {
            for (String queryColumnVo : queryColumnVos) {
                FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(queryColumnVo);
                if (fieldBeanByDisplay == null) {
                    continue;
                }
                queryColumns.add(fieldBeanByDisplay.getColumnName());
            }
        }
        for (FormWhereCondition conditionVo : conditionVos) {
            FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(conditionVo.getDisplay());
            if (fieldBeanByDisplay == null) {
                if (conditionVo.getDisplay().equals("ID") || conditionVo.getDisplay().equals("id")) {
                    conditionVo.setFieldName(conditionVo.getDisplay());
                }
                continue;
            }
            conditionVo.setFieldName(fieldBeanByDisplay.getColumnName());
        }

        Map<String, Object> generateSql = generateSql(queryColumns, conditionVos, tableName);
        String sql = (String) generateSql.get("sql");
        List<Object> params = (List<Object>) generateSql.get("params");
        JDBCAgent jdbcAgent = new JDBCAgent();
        List<FormColumn> columns = new ArrayList<>();
        try {
            jdbcAgent.execute(sql, params);
            List list = jdbcAgent.resultSetToList();
            for (Object o : list) {
                FormColumn column = new FormColumn();
                Map<String, Object> columnMap = (Map<String, Object>) o;
                List<FormFieldVo> vos = new ArrayList<>();
                for (String key : columnMap.keySet()) {
                    FormFieldVo fieldVo = new FormFieldVo();
                    if (fieldMap4Name.containsKey(key)) {
                        FormFieldBean fieldBean = fieldMap4Name.get(key);
                        fieldVo.setDisplayName(fieldBean.getDisplay());
                        fieldVo.setValue(columnMap.get(key));
                        vos.add(fieldVo);
                    }
                }
                column.setVos(vos);
                if (columnMap.get("id") != null) {
                    column.setId(columnMap.get("id") + "");
                }
                columns.add(column);
            }
            return columns;
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            jdbcAgent.close();
        }
        return null;
    }

    private Map<String, Object> generateSql(List<FormWhereCondition> conditions, String tableName) {
        if (tableName == null) {
            throw new IllegalArgumentException("tableName cannot be null or empty");
        }
        StringBuilder sqlBuilder = new StringBuilder("SELECT count(*) as countSize ");
        sqlBuilder.append(" from " + tableName);
        List<Object> params = new ArrayList<>();
        sqlBuilder.append(buildWhereClause(conditions,params));
        Map<String, Object> result = new HashMap<>();
        result.put("sql", sqlBuilder.toString());
        result.put("params", params);
        return result;
    }

    private Map<String, Object> generateSql(List<String> queryColumn, List<FormWhereCondition> conditions, String tableName) {
        if (tableName == null) {
            throw new IllegalArgumentException("tableName cannot be null or empty");
        }
        StringBuilder sqlBuilder = new StringBuilder("SELECT ");
        if (queryColumn == null || queryColumn.isEmpty()) {
            sqlBuilder.append("*");
        }

        for (int i = 0; i < queryColumn.size(); i++) {
            sqlBuilder.append(queryColumn.get(i));
            if (queryColumn.size() > 1 && i >= 0 && i < queryColumn.size() - 1) {
                sqlBuilder.append(",");
            }
        }

        if (queryColumn.size() > 0) {
            sqlBuilder.append(",`ID`");
        }

        sqlBuilder.append(" from " + tableName);
        List<Object> params = new ArrayList<>();
        sqlBuilder.append(buildWhereClause(conditions,params));
        Map<String, Object> result = new HashMap<>();
        result.put("sql", sqlBuilder.toString());
        result.put("params", params);
        return result;
    }

    private Map<String, Object> generateSql(List<FormUpdateField> fieldValues, String tableName,List<FormWhereCondition> conditions) {
        if (fieldValues == null || fieldValues.isEmpty()) {
            throw new IllegalArgumentException("Field values cannot be null or empty");
        }
        if (tableName == null || tableName.trim().isEmpty()) {
            throw new IllegalArgumentException("Table name cannot be null or empty");
        }
        StringBuilder sqlBuilder = new StringBuilder("UPDATE ").append(tableName).append(" SET ");
        List<Object> params = new ArrayList<>();
        // Build the SET clause
        int fieldCount = 0;
        for (FormUpdateField updateField : fieldValues) {
            if (updateField.getValue() == null || "".equals(updateField.getValue()) || "null".equals(updateField.getValue())) {
                continue;
            }
            if (fieldCount > 0) {
                sqlBuilder.append(", ");
            }
            if (updateField.getValue() instanceof String && ((String) updateField.getValue()).startsWith("DATE>")) {
                String oldValue = (String) updateField.getValue();
                sqlBuilder.append(updateField.getFieldName()).append(" = TO_DATE( ?, 'YYYY-MM-DD')");
                updateField.setValue(oldValue.substring(oldValue.indexOf(">") + 1));
            } else {
                sqlBuilder.append(updateField.getFieldName()).append(" = ?");
            }
            params.add(updateField.getValue());
            fieldCount++;
        }
        String whereClauseStr = buildWhereClause(conditions,params);
        // Append the WHERE clause
        sqlBuilder.append(whereClauseStr);
        // Create result map
        Map<String, Object> result = new HashMap<>();
        result.put("sql", sqlBuilder.toString());
        result.put("params", params);
        return result;
    }

    public Map<String,List<Object>> getMainFormTableAttachments(String formNo,Map<String,Object> sourceMap) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
        Map<String,List<Object>> attachmentTempMap = new HashMap<>();
        Set<String> removeKey = new HashSet<>();
        for (String key : sourceMap.keySet()) {
            FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(key);
            if(fieldBeanByDisplay == null ){
                continue;
            }
            if(fieldBeanByDisplay.getInputType().equals("image") ||
                    fieldBeanByDisplay.getInputType().equals("attachment")) {
                attachmentTempMap.put(fieldBeanByDisplay.getDisplay(),(List<Object>)sourceMap.get(key));
                removeKey.add(key);
            }
        }
        for (String key : removeKey) {
            sourceMap.remove(key);
        }
        return attachmentTempMap;
    }

    public Map<String,List<Object>> getSubFormTableAttachments(String formNo,Map<String,Object> sourceMap) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        List<FormTableBean> subTableBean = cap4FormBean.getSubTableBean();
        Map<String,List<Object>> attachmentTempMap = new HashMap<>();
        String tableName = null;
        for (String key : sourceMap.keySet()) {
            tableName = key;
        }
        String finalTableName = tableName;
        FormTableBean tableBean = subTableBean.stream().filter(s->s.getTableName().equals(finalTableName)).collect(Collectors.toList()).get(0);
        List<Map<String,Object>> tableData = (List<Map<String,Object>>)sourceMap.get(tableName);
        Set<String> removeKey = new HashSet<>();
        for (Map<String, Object> rowData : tableData) {
            for (String key : rowData.keySet()) {
                FormFieldBean fieldBeanByDisplay = tableBean.getFieldBeanByDisplay(key);
                if(fieldBeanByDisplay == null ){
                    continue;
                }
                if(fieldBeanByDisplay.getInputType().equals("image") ||
                        fieldBeanByDisplay.getInputType().equals("attachment")) {
                    attachmentTempMap.put(fieldBeanByDisplay.getDisplay(),(List<Object>)sourceMap.get(key));
                    removeKey.add(key);
                }
            }
            for (String key : removeKey) {
                rowData.remove(key);
            }
            removeKey.clear();
        }
        return attachmentTempMap;
    }

    public void addSubTableRecord(String subTableName,List<Object> data,String formNo,String formId) {
        JDBCAgent agent = new JDBCAgent();
        try {
            FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
            FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
            List<FormTableBean> tableBean = cap4FormBean.getSubTableBean();
            for (FormTableBean bean : tableBean) {
                if(!bean.getTableName().equals(subTableName)) {
                    continue;
                }
                for (Object column : data) {
                    Map<String,Object> map = (Map<String,Object>) column;
                    Map<String,Object> tempMap = new HashMap<>();
                    for (String key : map.keySet()) {
                        FormFieldBean fieldBeanByDisplay = bean.getFieldBeanByDisplay(key);
                        if(fieldBeanByDisplay == null) {
                            continue;
                        }
                        tempMap.put(fieldBeanByDisplay.getColumnName(),map.get(key));
                    }
                    tempMap.put("formmain_id",formId);
                    tempMap.put("sort",1);
                    tempMap.put("ID",Math.abs(UUID.randomUUID().getLeastSignificantBits()));
                    Map<String, Object> insertSql = generateInsertSql(tempMap, subTableName);
                    agent.execute((String)insertSql.get("sql"),(List<Object>)insertSql.get("params"));
                }
            }
        } catch (Exception e) {

        } finally {
            agent.close();
        }
    }

    public void rebuildSubTableRecord(String subTableName,List<Object> data,String formNo,String formId) {
        String deleteSql = "delete from " + subTableName + " where formmain_id = ? ";
        JDBCAgent agent = new JDBCAgent();
        try {
            agent.execute(deleteSql, Arrays.asList(formId));
            FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
            FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
            List<FormTableBean> tableBean = cap4FormBean.getSubTableBean();
            for (FormTableBean bean : tableBean) {
                if(!bean.getTableName().equals(subTableName)) {
                    continue;
                }
                for (Object column : data) {
                    Map<String,Object> map = (Map<String,Object>) column;
                    Map<String,Object> tempMap = new HashMap<>();
                    for (String key : map.keySet()) {
                        FormFieldBean fieldBeanByDisplay = bean.getFieldBeanByDisplay(key);
                        if(fieldBeanByDisplay == null) {
                            continue;
                        }
                        tempMap.put(fieldBeanByDisplay.getColumnName(),map.get(key));
                    }
                    tempMap.put("formmain_id",formId);
                    tempMap.put("sort",1);
                    tempMap.put("ID",Math.abs(UUID.randomUUID().getLeastSignificantBits()));
                    Map<String, Object> insertSql = generateInsertSql(tempMap, subTableName);
                    agent.execute((String)insertSql.get("sql"),(List<Object>)insertSql.get("params"));
                }
            }
        } catch (Exception e) {

        } finally {
            agent.close();
        }
    }

    public void handleEnumDeptEtc(Map<String,Object> map,String formNo) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
        for (String key : map.keySet()) {
            FormFieldBean fieldBean = masterTableBean.getFieldBeanByDisplay(key);
            if(fieldBean == null) {
                continue;
            }
            switch (fieldBean.getInputType()) {
                case "select": if(fieldBean.getEnumId() != 0l) {
                    String enumItemId = EnumMapUtils.getEnumItemValueByEnumId((String)map.get(key),fieldBean.getEnumId());
                    map.put(key,enumItemId);
                } break;
                case "image":break;
                case "attachment": break;
                case "account": break;
                case "department": break;
                case "radio": break;
                case "member":break;
                case "checkbox":
                case "date":
                case "text":break;
                default: break;

            }
        }
    }

    public void handleSubTableEnumDeptEtc(Map<String,Object> map,String formNo) throws BusinessException {
        FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
        List<FormTableBean> subTableBean = cap4FormBean.getSubTableBean();
        for (FormTableBean tableBean : subTableBean) {
            String tableName = null;
            for (String key : map.keySet()) {
                tableName = key;
            }
            if(!tableBean.getTableName().equals(tableName)) {
                continue;
            }
            List<Map<String,Object>> subDatas = (List<Map<String, Object>>) map.get(tableName);
            for (Map<String, Object> subData : subDatas) {
                for (String key : subData.keySet()) {
                    FormFieldBean fieldBean = tableBean.getFieldBeanByDisplay(key);
                    if(fieldBean == null) {
                        continue;
                    }
                    switch (fieldBean.getInputType()) {
                        case "select": if(fieldBean.getEnumId() != 0l) {
                            String enumItemId = EnumMapUtils.getEnumItemValueByEnumId((String)subData.get(key),fieldBean.getEnumId());
                            subData.put(key,enumItemId);
                        } break;
                        case "image":break;
                        case "attachment": break;
                        case "account": break;
                        case "department": break;
                        case "radio": break;
                        case "member":break;
                        case "checkbox":
                        case "date":
                        case "text":break;
                        default: break;

                    }
                }
            }
        }
    }

    public boolean isMasterTableFile(String displayName,String formNo) {
        FormApi4Cap4 formApi4Cap4 =  (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
        try {
            FormBean cap4FormBean = formApi4Cap4.getFormByFormCode(formNo);
            FormTableBean masterTableBean = cap4FormBean.getMasterTableBean();
            FormFieldBean fieldBeanByDisplay = masterTableBean.getFieldBeanByDisplay(displayName);
            return fieldBeanByDisplay.getInputType().equals("image") || fieldBeanByDisplay.getInputType().equals("attachment");
        } catch (BusinessException e) {

        }
        return false;
    }

    private Map<String, Object> generateInsertSql(Map<String, Object> data, String tableName) {
        if (tableName == null || tableName.isEmpty()) {
            throw new IllegalArgumentException("tableName cannot be null or empty");
        }
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("data cannot be null or empty");
        }
        StringBuilder sqlBuilder = new StringBuilder("INSERT INTO " + tableName + " (");
        List<Object> params = new ArrayList<>();
        // 拼接字段名
        StringBuilder columns = new StringBuilder();
        // 拼接字段值
        StringBuilder values = new StringBuilder();
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            // 拼接字段名
            if (columns.length() > 0) {
                columns.append(", ");
            }
            columns.append(entry.getKey());
            // 拼接值，使用占位符 ?
            if (values.length() > 0) {
                values.append(", ");
            }
            values.append("?");
            // 将值加入 params 列表
            params.add(entry.getValue());
        }
        // 完善 SQL 语句
        sqlBuilder.append(columns).append(") VALUES (").append(values).append(");");
        Map<String, Object> result = new HashMap<>();
        result.put("sql", sqlBuilder.toString());
        result.put("params", params);
        return result;
    }

    /**
     * 动态生成 WHERE 子句
     * @param conditions 条件集合
     * @param params 参数列表（引用传递）
     * @return 拼接后的 WHERE 子句（包含 WHERE 关键字）
     */
    private String buildWhereClause(List<FormWhereCondition> conditions, List<Object> params) {
        if (conditions == null || conditions.isEmpty()) {
            return "";
        }

        StringBuilder whereClause = new StringBuilder(" WHERE ");
        int conditionIndex = 0;

        for (FormWhereCondition condition : conditions) {
            // 处理括号起始
            if (condition.isStartWithBracket()) {
                whereClause.append("(");
            }

            // 字段名校验
            String fieldName = condition.getFieldName();
            ClauseFactor factor = condition.getClauseFactor();
            String operator = parseOperator(factor);

            // 构建条件表达式
            String conditionExpr;
            if (factor.isNullType()) {
                // 处理 NULL/NOT NULL 条件（无需参数）
                conditionExpr = String.format("%s %s", fieldName, operator);
            } else {
                // 处理普通条件（带占位符）
                conditionExpr = String.format("%s %s ?", fieldName, operator);
                // 处理函数模板（如 TO_DATE）
                if (condition.getIndex() != null) {
                    conditionExpr = conditionExpr.replace("?", condition.getIndex());
                }
                // 添加参数值
                params.add(condition.getValue());
            }

            whereClause.append(conditionExpr);

            // 处理括号闭合
            if (condition.isEndWithBracket()) {
                whereClause.append(")");
            }

            // 添加连接符（AND/OR）
            if (conditionIndex < conditions.size() - 1) {
                whereClause.append(" ").append(condition.getConcatFactor()).append(" ");
            }
            conditionIndex++;
        }

        return whereClause.toString();
    }

    /**
     * 校验字段名合法性（防止 SQL 注入）
     */
    private String validateFieldName(String fieldName) {
        if (!fieldName.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
            throw new IllegalArgumentException("非法字段名: " + fieldName);
        }
        return fieldName;
    }

    /**
     * 解析运算符映射（eq -> =, lt -> < 等）
     */
    private String parseOperator(ClauseFactor factor) {
        if(factor == null) {
            return "=";
        }
        switch (factor) {
            case EQ: return "=";
            case GT: return ">";
            case GE: return ">=";
            case LT: return "<";
            case LE: return "<=";
            case LIKE: return "LIKE";
            case NULL: return "IS NULL";      // 空值判断
            case NOT_NULL: return "IS NOT NULL"; // 非空判断
            default: throw new UnsupportedOperationException("不支持的运算符: " + factor);
        }
    }


}