package com.moka.gdtauto.task;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.moka.gdtauto.entity.AdAutoConf;
import com.moka.gdtauto.entity.AdPlanConf;
import com.moka.gdtauto.service.AdAutoConfService;
import com.moka.gdtauto.service.AdPlanAutoExecutor;
import com.moka.gdtauto.service.AdPlanConfService;
import com.moka.gdtauto.service.AdPlanCreativeAutoExecutor;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;

@Component
@AllArgsConstructor
@Slf4j
public class AdAutoTask {

    private final AdAutoConfService adAutoConfService;
    private final AdPlanAutoExecutor adPlanAutoExecutor;
    private final AdPlanCreativeAutoExecutor adPlanCreativeAutoExecutor;
    private final AdPlanConfService adPlanConfService;
    // private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    @Scheduled(cron = "0 0/10 * * * ?")
    @SchedulerLock(name = "ad-plan-auto-task", lockAtMostFor = "9m", lockAtLeastFor = "2m")
    public void adPlanAutoTask() {
        log.info("AdPlanAutoTask execute");
        List<AdAutoConf> confList = adAutoConfService.lambdaQuery().list();
        confList.forEach(conf -> adPlanAutoExecutor.asyncExecute(conf));
    }

    @Scheduled(cron = "30 0/10 * * * ?")
    @SchedulerLock(name = "ad-creative-auto-task", lockAtMostFor = "9m", lockAtLeastFor = "2m")
    public void adCreativeAutoTask() {
        log.info("AdCreativeAutoTask execute");
        List<AdAutoConf> confList = adAutoConfService.lambdaQuery().list();
        confList.forEach(conf -> adPlanCreativeAutoExecutor.asyncExecute(conf));
    }

    @Scheduled(cron = "0 20 0 * * ?")
    @SchedulerLock(name = "ad-auto-delete-task", lockAtMostFor = "9m", lockAtLeastFor = "2m")
    public void adAutoDeleteTask() {
        log.info("AdAutoDeleteTask execute");
        // 3天前
        LocalDateTime threeDaysAgo = LocalDateTime.now().minusDays(3);
        List<AdPlanConf> confList = 
            adPlanConfService.lambdaQuery()
            .lt(AdPlanConf::getCreateTime, threeDaysAgo)
            .orderByDesc(AdPlanConf::getId)
            .list();
        
        if (confList.isEmpty()) {
            log.info("没有需要删除的广告计划配置");
            return;
        }
        
        // 使用虚拟线程并发执行，Semaphore限制最大并发数为10
        Semaphore semaphore = new Semaphore(10);
        CountDownLatch latch = new CountDownLatch(confList.size());
        ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
        
        for (AdPlanConf conf : confList) {
            executor.submit(() -> {
                try {
                    semaphore.acquire();
                    adPlanConfService.gdtAdgroupPatrolDelete(conf);
                } catch (InterruptedException e) {
                    log.error("获取信号量被中断，confId={}", conf.getId(), e);
                    Thread.currentThread().interrupt();
                } catch (Exception e) {
                    log.error("删除广告计划配置失败，confId={}", conf.getId(), e);
                } finally {
                    semaphore.release();
                    latch.countDown();
                }
            });
        }
        
        // 等待所有任务完成
        try {
            latch.await();
        } catch (InterruptedException e) {
            log.error("等待虚拟线程任务完成被中断", e);
            Thread.currentThread().interrupt();
        } finally {
            executor.shutdown();
        }
        
        log.info("AdAutoDeleteTask 完成，共处理 {} 个配置", confList.size());
    }
}
