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

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.stm.essearch.stlib.service.IStlibService;
import org.stm.essearch.stlib.pojo.EsQueryVo;
import org.stm.essearch.stlib.pojo.PageResult;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class StlibService implements IStlibService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public PageResult search(EsQueryVo params,int pageNo,int pageSize) {
        try {
            SearchRequest request = new SearchRequest("mapping_common");
            buildBasicQuery(params, request);
            request.source().from((pageNo - 1) * pageSize).size(pageSize);
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            return handleResponse(response);
        } catch (IOException e) {
            throw new RuntimeException("搜索数据失败", e);
        }
    }

    private void buildBasicQuery(EsQueryVo params, SearchRequest request) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        String scType = params.getSctype();
        if (StringUtils.isNotBlank(scType)) {
            boolQuery.filter(QueryBuilders.termQuery("sctype", scType));
        }
        FunctionScoreQueryBuilder functionScoreQuery = QueryBuilders.functionScoreQuery(
                boolQuery, // 原始查询，boolQuery
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{ // function数组
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                QueryBuilders.termQuery("isAD", true), // 过滤条件
                                ScoreFunctionBuilders.weightFactorFunction(10) // 算分函数
                        )
                }
        );
        request.source().query(functionScoreQuery);
    }

    private PageResult handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        SearchHit[] hits = searchHits.getHits();
        List<EsQueryVo> dataList = new ArrayList<>(hits.length);
        for (SearchHit hit : hits) {
            String json = hit.getSourceAsString();
            EsQueryVo esQueryVo = JSON.parseObject(json, EsQueryVo.class);
            Map<String, HighlightField> map = hit.getHighlightFields();
            if (map != null && !map.isEmpty()) {
                HighlightField highlightField = map.get("name");
                if (highlightField != null) {
                    String hName = highlightField.getFragments()[0].toString();
                    esQueryVo.setName(hName);
                }
            }
            dataList.add(esQueryVo);
        }
        return new PageResult(total, dataList);
    }
}
