package top.r3944realms.docchecktoolrefactored.ui.task;

import javafx.concurrent.Task;
import lombok.extern.slf4j.Slf4j;
import top.r3944realms.docchecktoolrefactored.System;
import top.r3944realms.docchecktoolrefactored.ThreadPoolManager;
import top.r3944realms.docchecktoolrefactored.core.HashFileGenerator;
import top.r3944realms.docchecktoolrefactored.util.LoggerMarker;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
public class HashFileGenerationTask extends Task<String> {
    private final HashFileGenerator generator;
    private final File finalOutputFile;
    private final List<File> folders;
    private ExecutorService executor;
    private Future<?> future;

    public HashFileGenerationTask(File finalOutputFile, List<File> folders) {
        this.finalOutputFile = finalOutputFile;
        this.folders = folders;
        this.generator = new HashFileGenerator();
    }

    @Override
    protected String call() throws Exception {
        log.info(LoggerMarker.DEBUG_MARKER, "开始执行哈希文件生成任务");
        updateMessage("开始生成哈希文件...");

        // 传递多个文件夹路径
        List<Path> folderPaths = folders.stream().map(File::toPath).collect(ArrayList::new,
                ArrayList::add,
                ArrayList::addAll);

        generator.setCallback((current, total) -> {
            updateProgress(current, total);
            updateMessage("处理文件: " + current + "/" + total);
            if (current % 5000 == 0 || current == total) {
                log.info(LoggerMarker.DEBUG_MARKER, "处理进度: {}/{}", current, total);
            }
        });

        // 使用单独的线程执行生成任务，以便支持超时和取消
        executor = ThreadPoolManager.createPool("hash-file-generate-pool", 1);
        future = executor.submit(() -> {
            try {
                generator.generateHashFile(folderPaths, finalOutputFile.toPath());
            } catch (IOException | InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        try {
            // 设置超时时间
            long timeoutSeconds = System.getSetting().getTaskTimeout();
            future.get(timeoutSeconds, TimeUnit.SECONDS);

            log.info(LoggerMarker.DEBUG_MARKER, "哈希文件生成任务完成，输出文件: {}", finalOutputFile.getAbsolutePath());
            return "哈希列表文件已生成: " + finalOutputFile.getAbsolutePath();

        } catch (TimeoutException e) {
            String errorMsg = "哈希文件生成任务超时 (" + System.getSetting().getTaskTimeout() + "秒，请考虑在‘文件’-‘设置’里增加‘步骤任务超时时间’)";
            updateMessage(errorMsg);
            log.warn(LoggerMarker.DEBUG_MARKER, errorMsg);
            throw new RuntimeException(errorMsg, e);

        } catch (ExecutionException e) {
            String errorMsg = "哈希文件生成失败: " + e.getCause().getMessage();
            updateMessage(errorMsg);
            log.error(LoggerMarker.DEBUG_MARKER, errorMsg, e);
            throw new RuntimeException(errorMsg, e.getCause());

        } catch (InterruptedException e) {
            updateMessage("哈希文件生成任务被取消");
            log.info(LoggerMarker.DEBUG_MARKER, "哈希文件生成任务被取消");
            Thread.currentThread().interrupt();
            throw e;

        } finally {
            // 清理资源
            if (executor != null) {
                executor.shutdownNow();
            }
        }
    }

    @Override
    protected void cancelled() {
        super.cancelled();
        log.info(LoggerMarker.DEBUG_MARKER, "哈希文件生成任务已取消");
        updateMessage("正在取消哈希文件生成任务...");

        // 先取消 Future
        if (future != null && !future.isDone()) {
            future.cancel(true);
        }

        // 优雅关闭执行器
        if (executor != null) {
            try {
                executor.shutdown(); // 先尝试正常关闭
                if (!executor.awaitTermination(2, TimeUnit.SECONDS)) {
                    executor.shutdownNow(); // 强制关闭
                    executor.awaitTermination(1, TimeUnit.SECONDS);
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }

        updateMessage("哈希文件生成任务已取消");
    }
}
