package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import com.yeejoin.amos.boot.module.common.api.entity.EsEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.stereotype.Component;

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


@Component
@RequiredArgsConstructor
@Slf4j
public class EsBulkService {

    private final RestHighLevelClient restHighLevelClient;

    private final ElasticsearchConverter converter; // 依赖注入


    public <T> void bulkUpsert(String index, List<EsEntity<T>> list) {
        BulkRequest request = new BulkRequest();
        list.forEach(item -> {
            Map<String, Object> docData = converter.mapObject(item.getData());
            request.add(new UpdateRequest(index, item.getId())
                    .doc(docData)
                    .upsert(docData));
        });
        try {
            restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("批量写入数据失败:{}", e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }


    /**
     * 批量更新指定索引中的文档字段
     *
     * @param documentIdFieldsMap key:  要更新的文档ID列表 ,value: 需要更新的字段映射（字段名 → 新值）
     * @param targetIndex         目标索引名称
     * @throws RuntimeException 当ES操作失败时抛出
     */
    public void bulkUpdateFieldsByIds(Map<String, Map<String, Object>> documentIdFieldsMap, String targetIndex) {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            documentIdFieldsMap.forEach((documentId, fieldsToUpdate) -> {
                // 构建批量请求
                UpdateRequest updateRequest = new UpdateRequest(targetIndex, documentId).doc(fieldsToUpdate, XContentType.JSON);
                bulkRequest.add(updateRequest);
            });
            BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            // 更详细的错误日志记录
            if (response.hasFailures()) {
                Arrays.stream(response.getItems())
                        .filter(BulkItemResponse::isFailed)
                        .forEach(item -> log.error("Failed to update {}: {}",
                                item.getId(),
                                item.getFailureMessage()));
            }
        } catch (IOException e) {
            log.error("批量更新指定索引中的文档字段: batchSize={}, index={}", documentIdFieldsMap.size(), targetIndex, e);
        }
    }
}
