package org.jeecg.modules.stm.essearch.stlib.service.impl;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.elasticsearch.core.search.Hit;

import co.elastic.clients.elasticsearch.core.search.HighlightField;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.stm.essearch.stlib.service.IStlibService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.jeecg.modules.stm.stlib.pojo.EsQueryVo;
import org.jeecg.modules.stm.stlib.pojo.PageResult;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class StlibService implements IStlibService {

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    @Override
    public PageResult search(EsQueryVo params, int pageNo, int pageSize) {
        try {
            // 构建搜索请求
            SearchRequest request = SearchRequest.of(s -> s
                    .index("mapping_common")
                    .from((pageNo - 1) * pageSize)
                    .size(pageSize)
                    .query(buildBasicQuery(params))
                    .highlight(h -> h
                            .fields("name", HighlightField.of(hf -> hf))
                    )
            );

            // 执行搜索
            SearchResponse<EsQueryVo> response = elasticsearchClient.search(request, EsQueryVo.class);
            return handleResponse(response);
        } catch (IOException e) {
            throw new RuntimeException("搜索数据失败", e);
        }
    }

    private Query buildBasicQuery(EsQueryVo params) {
        // 构建 Bool 查询
        BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();

        // 添加 term 查询条件
        String scType = params.getSctype();
        if (StringUtils.isNotBlank(scType)) {
            boolQueryBuilder.filter(f -> f
                    .term(t -> t
                            .field("sctype")
                            .value(v -> v.stringValue(scType))
                    )
            );
        }

        // 构建 Function Score 查询
        FunctionScoreQuery.Builder functionScoreBuilder = new FunctionScoreQuery.Builder();

        // 设置查询条件
        functionScoreBuilder.query(q -> q
                .bool(boolQueryBuilder.build())
        );

        // 添加过滤条件和权重函数
        List<FunctionScore> functions = new ArrayList<>();
        functions.add(FunctionScore.of(f -> f
                .filter(fq -> fq
                        .term(t -> t
                                .field("isAD")
                                .value(v -> v.booleanValue(true))
                        )
                )
                .weight(10.0)
        ));

        functionScoreBuilder.functions(functions);

        // 构建最终的查询
        return Query.of(q -> q
                .functionScore(functionScoreBuilder.build())
        );
    }

    private PageResult handleResponse(SearchResponse<EsQueryVo> response) {
        TotalHits total = response.hits().total();
        long totalHits = total != null ? total.value() : 0;

        List<Hit<EsQueryVo>> hits = response.hits().hits();
        List<EsQueryVo> dataList = new ArrayList<>(hits.size());

        for (Hit<EsQueryVo> hit : hits) {
            EsQueryVo esQueryVo = hit.source();
            if (esQueryVo == null) {
                // 如果 source 为 null，尝试从 JSON 解析
                String json = JSON.toJSONString(hit.fields());
                esQueryVo = JSON.parseObject(json, EsQueryVo.class);
            }

            // 处理高亮
            Map<String, List<String>> highlightMap = hit.highlight();
            if (highlightMap != null && !highlightMap.isEmpty()) {
                List<String> nameHighlights = highlightMap.get("name");
                if (nameHighlights != null && !nameHighlights.isEmpty()) {
                    esQueryVo.setName(nameHighlights.get(0));
                }
            }

            dataList.add(esQueryVo);
        }

        return new PageResult(totalHits, dataList);
    }

    // 如果需要原始的 JSON 处理方式，可以使用以下方法
    private PageResult handleResponseWithJson(SearchResponse<Object> response) {
        try {
            TotalHits total = response.hits().total();
            long totalHits = total != null ? total.value() : 0;

            List<Hit<Object>> hits = response.hits().hits();
            List<EsQueryVo> dataList = new ArrayList<>(hits.size());

            for (Hit<Object> hit : hits) {
                // 将 source 转换为 JSON 字符串
                String json = JSON.toJSONString(hit.source());
                EsQueryVo esQueryVo = JSON.parseObject(json, EsQueryVo.class);

                // 处理高亮
                Map<String, List<String>> highlightMap = hit.highlight();
                if (highlightMap != null && !highlightMap.isEmpty()) {
                    List<String> nameHighlights = highlightMap.get("name");
                    if (nameHighlights != null && !nameHighlights.isEmpty()) {
                        esQueryVo.setName(nameHighlights.get(0));
                    }
                }

                dataList.add(esQueryVo);
            }

            return new PageResult(totalHits, dataList);
        } catch (Exception e) {
            throw new RuntimeException("处理搜索结果失败", e);
        }
    }
}