package com.writeoff.module.scheduler.job;

import com.writeoff.module.scheduler.model.AsyncJob;
import com.writeoff.module.scheduler.service.AsyncJobService;
import com.writeoff.module.notification.service.NotificationDispatchService;
import com.writeoff.module.export.service.ExportTaskService;
import com.writeoff.security.AuthContext;
import com.writeoff.security.AuthScope;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class AsyncJobScheduler {
    private final AsyncJobService asyncJobService;
    private final NotificationDispatchService notificationDispatchService;
    private final ExportTaskService exportTaskService;
    private final int batchSize;
    private final boolean enabled;

    public AsyncJobScheduler(AsyncJobService asyncJobService,
                             NotificationDispatchService notificationDispatchService,
                             ExportTaskService exportTaskService,
                             @Value("${app.scheduler.batch-size:100}") int batchSize,
                             @Value("${app.scheduler.enabled:true}") boolean enabled) {
        this.asyncJobService = asyncJobService;
        this.notificationDispatchService = notificationDispatchService;
        this.exportTaskService = exportTaskService;
        this.batchSize = batchSize;
        this.enabled = enabled;
    }

    @Scheduled(fixedDelayString = "${app.scheduler.poll-interval-ms:3000}")
    public void schedule() {
        if (!enabled) {
            return;
        }
        List<AsyncJob> jobs = asyncJobService.fetchReadyJobs(batchSize);
        for (AsyncJob job : jobs) {
            try {
                if (job.getTenantId() != null && job.getTenantId() > 0) {
                    AuthContext.set(0L, job.getTenantId(), AuthScope.TENANT);
                } else {
                    AuthContext.clear();
                }
                asyncJobService.markRunning(job, "scheduler-1");
                try {
                    execute(job);
                    asyncJobService.markSuccess(job);
                } catch (Exception ex) {
                    asyncJobService.markFailed(job, ex);
                }
            } finally {
                AuthContext.clear();
            }
        }
    }

    private void execute(AsyncJob job) {
        switch (job.getJobType()) {
            case "AUDIT_REMIND":
            case "TEMPLATE_EXPIRE":
            case "EXPORT_REPORT":
                return;
            case "NOTIFICATION_DISPATCH":
                notificationDispatchService.processTask(job.getPayload());
                return;
            case "EXPORT_TASK":
                exportTaskService.processTask(job.getPayload());
                return;
            default:
                throw new IllegalArgumentException("Unsupported jobType: " + job.getJobType());
        }
    }
}
