package nckd.jxccl.base.common.utils;

import nckd.jxccl.base.common.constant.FormConstant;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.StringJoiner;

/**
* 查询字段构建器
* @author W.Y.C
* @date 2025/9/27 16:34
* @version 1.0
*/
public final class QueryFieldBuilder {

    private final StringJoiner selectJoiner;
    private final StringJoiner orderJoiner;



    private QueryFieldBuilder() {
        this.selectJoiner = new StringJoiner(",");
        this.orderJoiner = new StringJoiner(",");
    }

    public static QueryFieldBuilder create() {
        return new QueryFieldBuilder();
    }

    // ---------------- SELECT ----------------

    /**
     * 添加单个字段
     * 使用方式:
     * QueryFieldBuilder.create().add(FormConstant.ID_KEY).buildSelect();
     * 输出结果:
     * "ID_KEY"
     * @param parts 字段路径，可单级或多级
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder add(String... parts) {
        selectJoiner.add(joinParts(parts));
        return this;
    }

    /**
     * 添加多级路径 + 多个子字段
     * 使用方式:
     * builder.addGroup(new String[]{"HRPI_PEREDUEXP","EDUCATION_KEY"}, FormConstant.ID_KEY, FormConstant.NAME_KEY);
     * 输出结果:
     * "HRPI_PEREDUEXP.EDUCATION_KEY.ID_KEY,HRPI_PEREDUEXP.EDUCATION_KEY.NAME_KEY"
     * @param prefixParts 多级前缀数组
     * @param subFields 子字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder addGroup(String[] prefixParts, String... subFields) {
        Arrays.stream(subFields)
                .forEach(f -> selectJoiner.add(joinParts(concat(prefixParts, f))));
        return this;
    }

    /**
     * 添加固定三件套 ID + NUMBER + NAME
     * 使用方式:
     * builder.addIdNumberName(FormConstant.COMPANY_KEY);
     * 输出结果:
     * "COMPANY_KEY.ID,COMPANY_KEY.NUMBER,COMPANY_KEY.NAME"
     * @param prefixParts 字段前缀
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder addIdNumberName(String... prefixParts) {
        return addGroup(prefixParts,
                FormConstant.ID_KEY,
                FormConstant.NUMBER_KEY,
                FormConstant.NAME_KEY);
    }

    /**
     * 添加三件套 ID+NUMBER+NAME 并可扩展其他字段
     * 使用方式:
     * builder.addIdNumberNameWithExtras(new String[]{FormConstant.EDUCATION_KEY}, FormConstant.NCKD_SCORE, FormConstant.STARTDATE);
     * 输出结果:
     * "EDUCATION_KEY.ID,EDUCATION_KEY.NUMBER,EDUCATION_KEY.NAME,EDUCATION_KEY.NCKD_SCORE,EDUCATION_KEY.STARTDATE"
     * @param prefixParts 字段前缀
     * @param extraFields 扩展字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder addIdNumberNameWithExtras(String[] prefixParts, String... extraFields) {
        addIdNumberName(prefixParts);
        if (extraFields != null && extraFields.length > 0) {
            addGroup(prefixParts, extraFields);
        }
        return this;
    }

    /**
     * 添加三件套 ID+NUMBER+NAME 并可扩展其他字段
     * 使用方式:
     * builder.addIdNumberNameWithExtras(FormConstant.NCKD_SCORE, FormConstant.STARTDATE);
     * 输出结果:
     * "EDUCATION_KEY.ID,EDUCATION_KEY.NUMBER,EDUCATION_KEY.NAME,EDUCATION_KEY.NCKD_SCORE,EDUCATION_KEY.STARTDATE"
     * @param extraFields 扩展字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder addIdNumberNameWithExtras(String... extraFields) {
        return addIdNumberNameWithExtras(null, extraFields);
    }


    // ---------------- ORDER ----------------

    /**
     * 升序排序，支持多级路径
     * 使用方式:
     * builder.orderAsc(new String[]{HonorStudentConstant.NCKD_EVALUATIONRULE, FormConstant.RULE_DETAIL}, FormConstant.ID_KEY);
     * 输出结果:
     * "NCKD_EVALUATIONRULE.RULE_DETAIL.ID asc"
     * @param prefixParts 多级前缀数组
     * @param fieldParts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder orderAsc(String[] prefixParts, String... fieldParts) {
        Arrays.stream(fieldParts)
                .forEach(f -> orderJoiner.add(joinParts(concat(prefixParts, f))+" asc"));
        return this;
    }

    /**
     * 升序排序，单级路径
     * 使用方式:
     * builder.orderAsc(HonorStudentConstant.NCKD_SUMSCORE);
     * 输出结果:
     * "NCKD_SUMSCORE asc"
     * @param parts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder orderAsc(String... parts) {
        for (String part : parts) {
            orderJoiner.add(joinParts(part) + " asc");
        }
        return this;
    }

    /**
     * 升序排序，单级路径
     * 使用方式:
     * builder.addAsc(adminorg, number);
     * 输出结果:
     * "adminorg.number asc"
     * @param parts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder addAsc(String... parts) {
        orderJoiner.add(joinParts(parts) + " asc");
        return this;
    }

    /**
     * 降序排序，支持多级路径
     * 使用方式:
     * builder.orderDesc(new String[]{HonorStudentConstant.NCKD_EVALUATIONRULE, FormConstant.RULE_DETAIL}, FormConstant.ID_KEY);
     * 输出结果:
     * "NCKD_EVALUATIONRULE.RULE_DETAIL.ID desc"
     * @param prefixParts 多级前缀
     * @param fieldParts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder orderDesc(String[] prefixParts, String... fieldParts) {
        Arrays.stream(fieldParts)
                .forEach(f -> orderJoiner.add(joinParts(concat(prefixParts, f))+ " desc"));
        return this;
    }

    /**
     * 降序排序，单级路径
     * 使用方式:
     * builder.orderDesc(HonorStudentConstant.NCKD_SUMSCORE);
     * 输出结果:
     * "NCKD_SUMSCORE desc"
     * @param parts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder orderDesc(String... parts) {
        for (String part : parts) {
            orderJoiner.add(joinParts(part) + " desc");
        }
        return this;
    }

    /**
     * 降序排序，单级路径
     * 使用方式:
     * builder.addDesc(adminorg, number);
     * 输出结果:
     * "adminorg.number desc"
     * @param parts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder addDesc(String... parts) {
        orderJoiner.add(joinParts(parts) + " desc");
        return this;
    }

    /**
     * 默认排序，不指定 asc/desc（不指定数据库默认未asc）
     * 使用方式:
     * builder.orderBy(new String[]{HonorStudentConstant.USEORG_KEY}, FormConstant.ID_KEY);
     * 输出结果:
     * "USEORG_KEY.ID_KEY"
     * @param prefixParts 多级前缀
     * @param fieldParts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder orderBy(String[] prefixParts, String... fieldParts) {
        Arrays.stream(fieldParts)
                .forEach(f -> orderJoiner.add(joinParts(concat(prefixParts, f))));
        return this;
    }

    /**
     * 默认排序，不指定 asc/desc（不指定数据库默认未asc），单级路径
     * 使用方式:
     * builder.orderBy(HonorStudentConstant.USEORG_KEY);
     * 输出结果:
     * "USEORG_KEY"
     * @param parts 排序字段
     * @return QueryFieldBuilder
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public QueryFieldBuilder orderBy(String... parts) {
        for (String part : parts) {
            orderJoiner.add(joinParts(part));
        }
        return this;
    }

    // ---------------- build ----------------

    /**
     * 构建 SELECT 字段字符串
     * 使用方式:
     * builder.buildSelect();
     * 输出结果:
     * "ID_KEY,COMPANY_KEY.ID,COMPANY_KEY.NUMBER,COMPANY_KEY.NAME,..."
     * @return String
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public String buildSelect() {
        return selectJoiner.toString();
    }

    /**
     * 构建 SELECT 字段字符串，并转为小写
     * 使用方式:
     * @return String 字段字符串
     * @author
     * @date: 2025/09/27
     */
    public String buildSelectLowerCase() {
        return buildSelect().toLowerCase();
    }

    /**
     * 构建并返回 SELECT 字段数组
     * 使用方式:
     * String[] fields = builder.buildSelectArray();
     * 输出结果:
     * ["ID_KEY", "COMPANY_KEY.ID", "COMPANY_KEY.NUMBER", "COMPANY_KEY.NAME", ...]
     * @return String[]
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public String[] buildSelectArray() {
        return selectJoiner.toString().split(",");
    }


    /**
     * 构建 SELECT 字段数组，并排除指定字段
     * 使用方式:
     * String[] fields = builder.buildSelectArrayExclude(FormConstant.ID_KEY, "COMPANY_KEY.NUMBER");
     * 输出结果:
     * ["COMPANY_KEY.ID", "COMPANY_KEY.NAME", ...] (排除了ID_KEY和COMPANY_KEY.NUMBER)
     * @param excludeFields 需要排除的字段数组
     * @return String[]
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public String[] buildSelectArrayExclude(String... excludeFields) {
        if (excludeFields == null || excludeFields.length == 0) {
            return buildSelectArray();
        }

        Set<String> excludeSet = new HashSet<>(Arrays.asList(excludeFields));
        return Arrays.stream(buildSelectArray())
                .filter(field -> !excludeSet.contains(field))
                .toArray(String[]::new);
    }

    /**
     * 构建 SELECT 字段数组，并排除指定前缀的字段
     * 使用方式:
     * String[] fields = builder.buildSelectArrayExcludePrefix("COMPANY_KEY", "HRPI_PEREDUEXP");
     * 输出结果:
     * ["ID_KEY", "EDUCATION_KEY.ID_KEY", "EDUCATION_KEY.NAME_KEY", ...] (排除了所有以COMPANY_KEY和HRPI_PEREDUEXP开头的字段)
     * @param excludePrefixes 需要排除的字段前缀数组
     * @return String[]
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public String[] buildSelectArrayExcludePrefix(String... excludePrefixes) {
        if (excludePrefixes == null || excludePrefixes.length == 0) {
            return buildSelectArray();
        }

        Set<String> excludePrefixSet = new HashSet<>(Arrays.asList(excludePrefixes));
        return Arrays.stream(buildSelectArray())
                .filter(field -> excludePrefixSet.stream().noneMatch(prefix -> field.startsWith(prefix + ".")))
                .toArray(String[]::new);
    }

    /**
     * 构建 ORDER BY 字段字符串
     * 使用方式:
     * builder.buildOrder();
     * 输出结果:
     * "NCKD_EVALUATIONRULE.ID asc,USEORG_KEY.ID,NCKD_SUMSCORE desc"
     * @return String
     * @author W.Y.C
     * @date: 2025/09/27
     */
    public String buildOrder() {
        return orderJoiner.toString();
    }

    /**
     * 构建小写的 ORDER BY 字段字符串
     * 使用方式:
     * builder.buildOrderLowerCase();
     * 输出结果:
     * "nckd_evaluationrule.id asc,useorg_key.id,nckd_sumscore desc"
     * @return String 小写的排序字段字符串
     * @author
     * @date: 2025/09/27
     */
    public String buildOrderLowerCase() {
        return orderJoiner.toString().toLowerCase();
    }

    public String[] buildOrderArray() {
        return orderJoiner.toString().split(",");
    }

    @Override
    public String toString() {
        return "SELECT: " + buildSelect() + "\nORDER: " + buildOrder();
    }

    // ---------------- 工具方法 ----------------

    /** 拼接多级路径 */
    private String joinParts(String... parts) {
        return String.join(".", parts);
    }


    private String[] concat(String[] prefixParts, String... subFields) {
        if (prefixParts == null || prefixParts.length == 0) {
            return subFields;
        }
        String[] result = Arrays.copyOf(prefixParts, prefixParts.length + subFields.length);
        System.arraycopy(subFields, 0, result, prefixParts.length, subFields.length);
        return result;
    }
}
