package com.yeejoin.amos.boot.module.jg.biz.job;

import cn.hutool.core.date.DateUtil;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.robot.AmosRequestContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Component
@RequiredArgsConstructor
@Slf4j
public class DataConsistencyJob {

    private final AmosRequestContext requestContext;

    private final DiscoveryClient discoveryClient;

    private final RestTemplate restTemplate; // 需要提前注入

    @Value("${spring.application.name}")
    private String applicationName;

//    @Scheduled(cron = "0 0 3 * * ?")
//    @SchedulerLock(name = "equipConsistencyJob", lockAtMostFor = "PT1H")
    public void execute() {
        List<ServiceInstance> instanceList = discoveryClient.getInstances(applicationName);
        int slots = instanceList.size();
        Executor executor = Executors.newFixedThreadPool(slots);
        HttpHeaders headers = this.builderHeaders();
        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        List<CompletableFuture<Void>> futures = new ArrayList<>();
        String batchNo = DateUtil.today();
        for (int i = 0; i < slots; i++) {
            int index = i;
            ServiceInstance instance = instanceList.get(i);
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                String baseUrl = instance.getUri().toString();
                String apiUrl = baseUrl + "/jg/dataHandler/sync-equip/shard?shard={shard}&slots={slots}&batchNo={batchNo}";
                Map<String, Object> params = new HashMap<>();
                params.put("shard", index);
                params.put("slots", slots);
                params.put("batchNo", batchNo);
                restTemplate.exchange(
                        apiUrl,
                        HttpMethod.PUT,
                        requestEntity,
                        FeignClientResult.class,
                        params
                );
            }, executor);
            futures.add(future);
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                    .exceptionally(ex -> {
                        log.error("任务执行异常", ex);
                        return null;
                    })
                    .join();
        }
    }

    private HttpHeaders builderHeaders() {
        HttpHeaders httpheaders = new HttpHeaders();
        httpheaders.add("appKey", requestContext.getAppKey());
        httpheaders.add("product", requestContext.getProduct());
        httpheaders.add("token", requestContext.getToken());
        httpheaders.setContentType(MediaType.APPLICATION_JSON);
        return httpheaders;
    }

}
