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

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.analysis.Analyzer;
import co.elastic.clients.elasticsearch._types.analysis.StandardAnalyzer;
import co.elastic.clients.elasticsearch._types.mapping.IntegerNumberProperty;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.elasticsearch.indices.get_mapping.IndexMappingRecord;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * @author reghao
 * @date 2025-03-12 10:45:52
 */
@Slf4j
@Service
public class IndexService {
    private final ElasticsearchClient esClient;

    public IndexService(ElasticService elasticService) {
        this.esClient = elasticService.getElasticsearchClient();
    }

    public void createIndex(String indexName, Map<String, Property> propertyMap) throws IOException {
        String type = "_doc";
        ExistsRequest existsRequest = new ExistsRequest.Builder()
                .index(indexName)
                .local(false)
                .build();
        BooleanResponse exists = esClient.indices().exists(existsRequest);
        if(exists.value()) {
            log.info("索引 {} 已存在!", indexName);
            return;
        }

        // 设置分词
        IndexSettingsAnalysis indexSettingsAnalysis = new IndexSettingsAnalysis.Builder()
                .analyzer("StandardAnalyzer", new Analyzer.Builder().standard(new StandardAnalyzer.Builder().build()).build())
                .build();

        IndexSettings indexSettings = new IndexSettings.Builder()
                //.analysis(indexSettingsAnalysis)
                .numberOfShards("10")
                .numberOfReplicas("10")
                //.refreshInterval(Time.of(t -> 5))
                .build();
        TypeMapping typeMapping = new TypeMapping.Builder()
                .properties(propertyMap)
                .build();
        CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder()
                .index(indexName)
                .settings(indexSettings)
                .mappings(typeMapping)
                //.aliases("ngxlog", new Alias.Builder().isWriteIndex(true).build())
                .build();
        CreateIndexResponse createIndexResponse = esClient.indices().create(createIndexRequest);
        if (createIndexResponse.acknowledged()) {
            log.info("索引 {} 创建成功!", indexName);
        }
    }

    public void updateMapping(String indexName) throws IOException {
        Map<String, Property> propertyMap = new HashMap<>();
        Property intProp = Property.of(builder -> builder.integer(IntegerNumberProperty.of(pro -> pro.index(true))));
        propertyMap.put("member", intProp);

        /*Property keywordProp = Property.of(builder -> builder.keyword(KeywordProperty.of(pro -> pro.index(true))));
        propertyMap.put("requestMethod", keywordProp);*/

        /*Property textProp = Property.of(builder -> builder.text(TextProperty.of(pro -> pro.index(true).analyzer("ik_max_word"))));
        propertyMap.put("requestUri", textProp);*/

        PutMappingRequest putMappingRequest = PutMappingRequest.of(m -> m.index(indexName).properties(propertyMap));
        PutMappingResponse putMappingResponse = esClient.indices().putMapping(putMappingRequest);
        boolean acknowledged = putMappingResponse.acknowledged();
        log.info("update mappings ack: {}", acknowledged);
    }

    public void deleteIndex(String indexName) throws IOException {
        ExistsRequest existsRequest = new ExistsRequest.Builder()
                .index(indexName)
                .local(false)
                .build();
        BooleanResponse exists = esClient.indices().exists(existsRequest);
        if(!exists.value()) {
            log.info("索引 {} 不存在!", indexName);
            return;
        }

        DeleteIndexResponse response = esClient.indices().delete(i -> i.index(indexName));
        if (!response.acknowledged()) {
        }
    }

    public void getMapping(String indexName) throws IOException {
        GetMappingRequest request = GetMappingRequest.of(builder -> builder.index(indexName));
        GetMappingResponse response = esClient.indices().getMapping(request);
        Map<String, IndexMappingRecord> result = response.result();
        log.info("{} mapping message: {}", indexName, result);
    }

    public void getIndex(String indexName) throws IOException {
        List<String> indexNames = new ArrayList<>();
        indexNames.add(indexName);
        GetIndexRequest request = GetIndexRequest.of(builder -> builder.index(indexNames));
        GetIndexResponse getIndexResponse = esClient.indices().get(request);
        Map<String, IndexState> result = getIndexResponse.result();
        result.entrySet().forEach(entry -> {
            log.info("key: {}, value: {}", entry.getKey(), entry.getValue());
        });
    }

    public void existIndex() throws IOException {
        List<String> indexName = new ArrayList<>();
        indexName.add("user");
        ExistsRequest request = ExistsRequest.of(builder -> builder.index(indexName));
        BooleanResponse response = esClient.indices().exists(request);
        log.info("exist: {}", response.value());
    }
}
