package cn.reghao.tnb.search.esapp.es;

import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.json.JsonData;

import java.util.List;

/**
 * @author reghao
 * @date 2026-01-03 16:40:03
 */
public class EsQuery {

    /**
     * 等值查询
     *
     * @param
     * @return
     * @date 2025-03-12 13:45:17
     */
    public static Query getTermQuery(String fieldName, String fieldValue) {
        String fieldName1 = "url";
        String fieldValue1 = "/datareceive/ReceiveData/SendContentResult\"";
        String fieldName2 = "requestMethod";
        String fieldValue2 = "POST";
        Query query = TermQuery.of(t -> t
                .field(fieldName).value(FieldValue.of(fieldValue))
        )._toQuery();
        return query;
    }

    /**
     * MatchQuery 搜索时, 首先会解析查询字符串, 进行分词，然后查询
     * TermQuery 搜索时, 会根据输入的查询内容进行搜索, 并不会解析查询内容，对它分词
     *
     * @param
     * @return
     * @date 2025-03-12 15:04:22
     */
    public static Query getMatchQuery() {
        String fieldName = "host";
        String searchText = "api.iquizoo.com";

        Query query = MatchQuery.of(m -> m.field(fieldName).query(searchText))._toQuery();
        return query;
    }

    /**
     * 多值查询, 相当于 SQL 语句中的 in 查询
     *
     * @param
     * @return
     * @date 2025-03-12 14:12:38
     */
    public static Query getTermsQuery() {
        String fieldName = "status";
        List<FieldValue> fieldValueList = List.of(FieldValue.of("401"), FieldValue.of("500"));

        Query query = TermsQuery.of(t ->
                t.field(fieldName).terms(TermsQueryField.of(q -> q.value(fieldValueList)))
        )._toQuery();
        return query;
    }

    /**
     * 或查询, 相当于 SQL 查询
     * SELECT * FROM test1 where (uid = 1 or uid =2) and phone = 12345678919
     *
     * @param
     * @return
     * @date 2025-03-12 13:46:26
     */
    public static Query getOrQuery() {
        Query query = BoolQuery.of(b ->
                b.should(m -> m.term(t -> t.field("status").value(FieldValue.of(401))))
                        .should(m -> m.term(t -> t.field("status").value(FieldValue.of(403))))
                        .must(m -> m.term(t -> t.field("host").value(FieldValue.of("api.iquizoo.com"))))
        )._toQuery();
        return query;
    }

    public static Query getAndQuery() {
        String fieldName1 = "status";
        String fieldValue1 = "200";

        String fieldName2 = "requestMethod";
        String fieldValue2 = "POST";

        Query query = BoolQuery.of(b -> b
                .must(m -> m.term(t -> t.field(fieldName1).value(FieldValue.of(fieldValue1))))
                .must(m -> m.term(t -> t.field(fieldName2).value(FieldValue.of(fieldValue2))))
        )._toQuery();
        return query;
    }

    /**
     * 模糊查询, 相当于 SQL 语句中的 like 查询
     *
     * @param
     * @return
     * @date 2025-03-12 14:11:45
     */
    public static Query getWildcardQuery() {
        Query query = BoolQuery.of(b ->
                b.must(m -> m.wildcard(t -> t.field("url").value("*result*")))
        )._toQuery();
        return query;
    }

    /**
     * 存在查询, 相当于 SQL 语句中的 exist
     *
     * @param
     * @return
     * @date 2025-03-12 14:20:26
     */
    public static Query getExistsQuery(String fieldName) {
        // 判断字段是否存在
        Query query = ExistsQuery.of(t -> t.field(fieldName))._toQuery();
        return query;
    }

    /**
     * 范围查询, 相当于 SQL 语句中的 > 和 <
     * gt 是大于，lt 是小于，gte 是大于等于，lte 是小于等于
     *
     * @param
     * @return
     * @date 2025-03-12 14:21:26
     */
    public static Query getRangeQuery(String fieldName) {
        String fieldName1 = "status";
        int start1 = 404;
        int start2 = 600;

        String dateValue = "2023-11-06";
        String start = String.format("%sT00:00:00Z", dateValue);
        String end = String.format("%sT23:59:59Z", dateValue);

        Query query = RangeQuery.of(t -> t.field(fieldName).gte(JsonData.of(start)).lte(JsonData.of(end)))._toQuery();
        return query;
    }

    /**
     * 正则查询
     *
     * @param
     * @return
     * @date 2025-03-12 14:22:18
     */
    public static Query getRegexpQuery() {
        Query query = RegexpQuery.of(t -> t.field("host").value("api.*"))._toQuery();
        return query;
    }

    public static Query getQuery() {
        Query query1 = MatchAllQuery.of(m -> m.queryName("host"))._toQuery();

        // 一般情况下有一个单词错误的情况下，fuzzy 查询可以找到另一个近似的词来代替，主要有以下场景：
        //
        //修改一个单词，如：box--->fox。
        //移除一个单词，如：black-->lack。
        //插入一个单词，如：sic-->sick。
        //转换两个单词顺序，如：act-->cat。
        Query query2 = FuzzyQuery.of(f -> f.field("host").value("lonel"))._toQuery();

        // 通过指定字段的前缀进行查询
        Query query = PrefixQuery.of(p -> p.field("host").value("api"))._toQuery();
        return query;
    }
}
