package com.beagle.base.common.listener;

import cn.hutool.core.collection.CollUtil;
import com.beagle.base.bean.vo.BasePointVO;
import com.beagle.base.bean.vo.BasePointsPropertiesParam;
import com.beagle.base.bean.vo.BaseSearchParam;
import com.beagle.base.bean.vo.BaseSearchPointCountParam;
import com.beagle.base.common.contant.CacheConstants;
import com.beagle.base.service.BaseService;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.rtdb.enums.DataSort;
import com.rtdb.model.FullPoint;
import com.rtdb.model.SearchCondition;
import com.rtdb.model.SearchConditionTotal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
@Component
public class ApplicationListener implements org.springframework.context.ApplicationListener<ApplicationReadyEvent> {

    @Resource
    private BaseService baseService;


    @Resource
    @Qualifier(value= "loadingCache")
    private LoadingCache<Object, Object> cache;
    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        // 初始化golden缓存
        // 调用 base/searchPointCount 接口
        BaseSearchPointCountParam baseSearchPointCountParam = new BaseSearchPointCountParam();
        baseSearchPointCountParam.setSort(DataSort.SORT_BY_ID);
        baseSearchPointCountParam.setCondition(new SearchConditionTotal());
        Integer count = baseService.searchPointCount(baseSearchPointCountParam);
        if (count == null) {
            log.error("调用 base/searchPointCount 接口返回的总数为空,跳过");
            return;
        }
        // 调用 base/search 接口
        BaseSearchParam baseSearchParam = new BaseSearchParam();
        baseSearchParam.setSort(DataSort.SORT_BY_ID);
        baseSearchParam.setCount(count);
        baseSearchParam.setCondition(new SearchCondition());
        int [] totalArray = baseService.search(baseSearchParam);
        if (totalArray == null) {
            log.error(" 调用 base/search 接口 返回的数据为空, 跳过");
            return;
        }
        // 调用 base/getPointsProperties 接口
        List<FullPoint> fullPointList = batchJob(totalArray);

        if (CollUtil.isEmpty(fullPointList)) {
            log.error("调用 base/getPointsProperties 接口 返回的数据为空，跳过");
            return;
        }
        fullPointList.forEach(each-> {
            BasePointVO basePointVO = new BasePointVO();
            basePointVO.setId(each.getBasePoint().getId());
            basePointVO.setTag(each.getBasePoint().getTag());
            basePointVO.setType(each.getBasePoint().getType());
            cache.put(CacheConstants.POINT_PREFIX + basePointVO.getId(), basePointVO);
            cache.put(CacheConstants.TAG_PREFIX + basePointVO.getTag(), basePointVO.getId());
        });
    }

    private List<FullPoint> batchJob(int [] array) {
        List<CompletableFuture<List<FullPoint>>> futures = new ArrayList<>();
        List<List<Integer>> batches = new ArrayList<>();
        int batchSize = 1;
        for (int start = 0; start < array.length; start += batchSize) {
            batches.add(Arrays.stream(array, start, Math.min(start + batchSize, array.length))
                    .boxed()
                    .collect(Collectors.toList()));
        }


        // 拆分任务
        for (int i = 0; i < batches.size(); i ++) {
            final int start = i;
            // 创建批处理异步任务
            CompletableFuture<List<FullPoint>> future = CompletableFuture.supplyAsync(() -> {
                // 处理当前批次的任务
                BasePointsPropertiesParam basePointsPropertiesParam = new BasePointsPropertiesParam();
                basePointsPropertiesParam.setIds(batches.get(start).stream().mapToInt(Integer::intValue).toArray());
                return baseService.getPointsProperties(basePointsPropertiesParam);
            });

            futures.add(future);
        }

        // 等待所有任务完成，并整合结果
        CompletableFuture<List<FullPoint>> allTasks =
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                .thenApply(v -> futures.stream()
                        .map(CompletableFuture::join)
                        .flatMap(List::stream)  // 等待所有任务并获取结果
                        .collect(Collectors.toList()));

        // 获取并处理最终的结果
        List<FullPoint> results = allTasks.join();  // 这里会阻塞，直到所有任务完成
        // 处理结果 (例如，打印数量)
        System.out.println("Total results processed: " + results.size());
        return results;
    }
}
