package top.r3944realms.docchecktoolrefactored.ui.task;

import javafx.concurrent.Task;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.docchecktoolrefactored.System;
import top.r3944realms.docchecktoolrefactored.core.DuplicateFinder;
import top.r3944realms.docchecktoolrefactored.core.MD5HashCalculator;
import top.r3944realms.docchecktoolrefactored.core.ScanningException;
import top.r3944realms.docchecktoolrefactored.io.scanner.RobustParallelScanner;
import top.r3944realms.docchecktoolrefactored.model.DuplicateGroup;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
public class DuplicateDocumentDetectionTask extends Task<String>{
    private final String folderPath;
    private final DuplicateFinder duplicateFinder;


    public DuplicateDocumentDetectionTask(String folderPath) {
        this.folderPath = folderPath;
        // 创建带进度更新的扫描器
        RobustParallelScanner scanner = new RobustParallelScanner(10);
        MD5HashCalculator hashCalculator = new MD5HashCalculator();
        // 进度监听的 DuplicateFinder
        this.duplicateFinder = new DuplicateFinder(scanner, hashCalculator, true);
    }


    @Override
    protected String call() throws Exception {
        updateMessage("正在初始化扫描...");


        Path rootPath = Paths.get(folderPath);
        if (!Files.exists(rootPath) || !Files.isDirectory(rootPath)) {
            throw new IllegalArgumentException("指定路径不是有效目录: " + folderPath);
        }
        duplicateFinder.applySetting(System.getSetting());

        // 用于统计文件总数
        AtomicInteger totalFiles = new AtomicInteger(0);

        // 使用 RobustParallelScanner 和 MD5HashCalculator 进行并行扫描和哈希计算
        // 设置进度回调
        duplicateFinder.setProgressCallback(new DuplicateFinder.ProgressCallback() {
            @Override
            public void onPhaseStarted(DuplicateFinder.Phase phase) {
                switch (phase) {
                    case GROUP_BY_SIZE:
                        updateMessage("正在按文件大小分组...");
                        break;
                    case CALCULATE_HASH:
                        updateMessage("正在计算可能重复文件的哈希值...");
                        break;
                }
            }

            @Override
            public void onPhaseProgress(DuplicateFinder.Phase phase, int current, int total) {
                if (total > 0) {
                    // 控制更新频率
                        String msg = switch (phase) {
                            case GROUP_BY_SIZE -> {
                                totalFiles.getAndIncrement();
                                yield String.format("正在按文件大小分组: %d/%d", current, total);
                            }
                            case CALCULATE_HASH -> String.format("正在计算哈希值: %d/%d", current, total);
                        };
                        updateMessage(msg);
                        updateProgress(current, total);
                }
            }

            @Override
            public void onPhaseCompleted(DuplicateFinder.Phase phase) {
                switch (phase) {
                    case GROUP_BY_SIZE:
                        updateMessage("文件大小分组完成");
                        break;
                    case CALCULATE_HASH:
                        updateMessage("哈希值计算完成");
                        break;
                }
            }
        });

        AtomicReference<List<DuplicateGroup>> resultRef = new AtomicReference<>();
        AtomicReference<Throwable> errorRef = new AtomicReference<>();
        CountDownLatch latch = new CountDownLatch(1);

        // 在单独线程中执行查找
        Thread findThread = new Thread(() -> {
            try {
                List<DuplicateGroup> duplicates = duplicateFinder.findDuplicates(rootPath);
                resultRef.set(duplicates);
            } catch (Exception e) {
                errorRef.set(e);
            } finally {
                latch.countDown();
            }
        });

        findThread.setDaemon(true);
        findThread.start();

        // 简单等待，Task取消时会自动中断
        long totalTimeout = System.getSetting().getTaskTimeout();
        if (!latch.await(totalTimeout, TimeUnit.SECONDS)) {
            duplicateFinder.shutdown();
            throw new TimeoutException(String.format("任务超时（%d秒），请考虑在‘文件’-‘设置’里增加‘步骤任务超时时间’", totalTimeout));
        }

        // 检查是否有错误
        if (errorRef.get() != null) {
            throw new RuntimeException(errorRef.get());
        } else if (!duplicateFinder.getErrors().isEmpty()) {
            throw new ScanningException(duplicateFinder.getErrors());
        }

        List<DuplicateGroup> duplicateGroups = resultRef.get();
        // 构建最终结果
        return generateResult(duplicateGroups, totalFiles,
                     duplicateFinder.getTargetFilesCount(),
                     duplicateFinder.getOtherFilesCount());
    }

   // Update method signature
private static @NotNull String generateResult(List<DuplicateGroup> duplicateGroups,
                                              AtomicInteger totalFiles,
                                              int targetFilesCount,
                                              int otherFilesCount) {
    StringBuilder result = new StringBuilder();

    // Calculate total duplicate files
    int totalDuplicateFiles = duplicateGroups.stream()
            .mapToInt(group -> group.fileMetas().size())
            .sum();

    int totalGroups = duplicateGroups.size();

    result.append(String.format("总共扫描文件数: %d\n", totalFiles.get()));
    result.append(String.format("其中目标文件(jpg jpeg png bmg gif tiff jp2 pdf ofd )数: %d\t", targetFilesCount));
    result.append(String.format(" 非目标文件数: %d\n", otherFilesCount));
    result.append(String.format("发现重复文件组数: %d\n", totalGroups));
    result.append(String.format("重复文件总数: %d\n", totalDuplicateFiles));

    // Rest of the existing implementation remains the same
    if (!duplicateGroups.isEmpty()) {
        result.append("\n详细重复文件信息:\n");
        result.append("----------------------------------------\n");

        int groupIndex = 1;
        for (DuplicateGroup group : duplicateGroups) {
            result.append(String.format("第 %d 组 (哈希值: %s, 大小: %d 字节)\n",
                    groupIndex, group.hash(), group.size()));

            int fileIndex = 1;
            for (var file : group.fileMetas()) {
                Path filePath = file.getPath();
                result.append(String.format("  文件%d: %s\n", fileIndex, filePath.toAbsolutePath()));
                fileIndex++;
            }
            result.append("\n");
            groupIndex++;
        }
    } else {
        result.append("\n没有发现重复文件\n");
    }

    result.append("检测完成!\n");
    return result.toString();
}


    @Override
    protected void cancelled() {
        super.cancelled();
        // 清理资源
        duplicateFinder.shutdown();
        updateMessage("操作已被取消");
    }

}
