package com.junmp.jyzb.utils;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class ElasticsearchUtil<T> {
    private final RestHighLevelClient client;



    public ElasticsearchUtil(RestHighLevelClient client) {
        this.client = client;
    }

    public List<T> searchAll(String typeName, int pageNum, int pageSize, Class<T> entityClass) throws IOException {
        if (pageNum < 0) pageNum = 0;

        SearchRequest request = new SearchRequest(typeName);
        SearchSourceBuilder builder = new SearchSourceBuilder();

        builder.from(pageNum * pageSize);
        builder.size(pageSize);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "超级根"));

        builder.query(boolQueryBuilder);
        builder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        request.source(builder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);

        ObjectMapper objectMapper = new ObjectMapper();
        return Arrays.stream(searchResponse.getHits().getHits())
                .map(SearchHit::getSourceAsString)
                .map(sourceAsString -> {
                    try {
                        return objectMapper.readValue(sourceAsString, entityClass);
                    } catch (IOException e) {
                        // 处理异常
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    public List<T> searchEntities(String typeName,String nickName, String index, Integer pageNum, Integer pageSize,Integer type, String keyword,String searchType, Class<T> entityClass) throws IOException {
        if (pageNum < 0) pageNum = 0;

        SearchRequest request = new SearchRequest(typeName);
        SearchSourceBuilder builder = new SearchSourceBuilder();

        builder.from(pageNum);
        builder.size(pageSize);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        MatchQueryBuilder matchQueryBuilder=new MatchQueryBuilder();
        if (searchType.equals("normal"))
        {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(index, keyword).operator(Operator.AND);
             boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.should(matchQueryBuilder);
            builder.query(boolQueryBuilder);
        } else if (searchType.equals("match")) {
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(index, keyword).operator(Operator.OR);
             boolQueryBuilder = QueryBuilders.boolQuery();

            boolQueryBuilder.should(matchQueryBuilder);

            builder.query(boolQueryBuilder);
        }

        // 如果 nickName 不为空，则同时匹配 nickName 和 typeName
        if (StringUtils.isNotBlank(nickName)) {
            MatchQueryBuilder nickNameQueryBuilder = QueryBuilders.matchQuery("nickName", nickName).operator(Operator.AND);
            boolQueryBuilder.should(nickNameQueryBuilder);
        }

        if (typeName.equals("orgName"))
        {
            builder.postFilter(new TermQueryBuilder("delFlag", 1));
        }
        if (ObjectUtil.isNotNull(type)){
            builder.postFilter(new TermQueryBuilder("type",type));
        }

      
        builder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        request.source(builder);
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);

        List<T> entityList = new ArrayList<>();
        for (SearchHit documentFields : searchResponse.getHits().getHits()) {
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            T entity = fromMap(sourceAsMap, entityClass);

            entityList.add(entity);
        }

        return entityList;
    }

    private T fromMap(Map<String, Object> sourceAsMap, Class<T> entityClass) {
        ObjectMapper objectMapper = new ObjectMapper(); // 使用 Jackson 库进行转换
        return objectMapper.convertValue(sourceAsMap, entityClass);
    }
}
