package cn.reghao.tnb.search.esapp.log.service;

import cn.reghao.jutil.jdk.web.log.NginxLog;
import cn.reghao.tnb.search.esapp.es.ElasticService;
import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.Result;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchAllQuery;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * @author reghao
 * @date 2025-03-12 10:45:58
 */
@Slf4j
@Service
public class NginxLogDocument {
    private final ElasticsearchClient esClient;
    private final ElasticsearchAsyncClient asyncClient;

    public NginxLogDocument(ElasticService elasticService) {
        this.esClient = elasticService.getElasticsearchClient();
        this.asyncClient = elasticService.getElasticsearchAsyncClient();
    }

    public void save(String indexName, NginxLog nginxLog) throws IOException {
        IndexResponse indexResponse = esClient.index(i -> i.index(indexName).id(nginxLog.getId()).document(nginxLog));
        String result = indexResponse.result().jsonValue();
        if (!"created".equals(result)) {
            log.error("add one document result: {}", indexResponse.result().jsonValue());
        }
    }

    public void saveAll(String indexName, List<NginxLog> nginxLogs) {
        List<BulkOperation> bulkOperations = new ArrayList<>();
        nginxLogs.forEach(p -> bulkOperations.add(BulkOperation.of(b -> b.index(c -> c.id(p.getId()).document(p)))));
        try {
            BulkResponse bulkResponse = esClient.bulk(s -> s.index(indexName).operations(bulkOperations));
            if (bulkResponse.errors()) {
                bulkResponse.items().forEach(b -> log.error("bulk response result = {}", b.result()));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void updateDocument(String indexName, NginxLog product) throws IOException {
        UpdateResponse<NginxLog> updateResponse = esClient.update(s -> s.index(indexName).id(product.getId()).doc(product), NginxLog.class);
        log.info("update doc result: {}", updateResponse.result());
    }

    public void update(String indexName, NginxLog nginxLog) throws IOException {
        String id = nginxLog.getId();
        IndexResponse response = esClient.index(i -> i.index(indexName).document(nginxLog).id(id));
        Result result = response.result();
        System.out.println(result.jsonValue());
    }

    public void deleteDocument(String indexName, String id) {
        try {
            DeleteResponse deleteResponse = esClient.delete(s -> s.index(indexName).id(id));
            log.info("del doc result: {}", deleteResponse.result());
        } catch (IOException e) {
            log.error("del doc failed, error: ", e);
        }
    }

    /*
     * 删除索引下的所有文档
     *
     * @param
     * @return
     * @date 2025-03-13 16:26:20
     */
    public void deleteAllDocument(String indexName) {
        try {
            DeleteByQueryRequest deleteByQueryRequest = DeleteByQueryRequest.of(s -> s.index(indexName)
                    .query(m -> m.matchAll(new MatchAllQuery.Builder().build()))
            );
            DeleteByQueryResponse deleteByQueryResponse = esClient.deleteByQuery(deleteByQueryRequest);
            log.info("del doc result: {}", deleteByQueryResponse.total());
        } catch (IOException e) {
            log.error("del doc failed, error: ", e);
        }
    }

    public void batchDelete(String indexName, List<String> ids) {
        List<BulkOperation> bulkOperations = new ArrayList<>();
        ids.forEach(a -> bulkOperations.add(BulkOperation.of(b -> b.delete(c -> c.id(a)))));
        try {
            BulkResponse bulkResponse = esClient.bulk(a -> a.index(indexName).operations(bulkOperations));
            bulkResponse.items().forEach(a -> log.info("batch del result: {}", a.result()));
            log.error("batch del bulk resp errors: {}", bulkResponse.errors());
        } catch (IOException e) {
            log.error("batch del doc failed, error: ", e);
        }
    }

    public void delete(String indexName) throws IOException {
        int id = 1;
        asyncClient.delete(i -> i.index(indexName).id("" + id)).whenComplete((success, failure)->{
            System.out.println(success.index());
            System.out.println(success.version());
        });
    }
}
