package top.imwork.window.silos.processor;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class ChapterSplitter {
    // 章节分隔符的正则表达式
    private static final Pattern CHAPTER_PATTERN = Pattern.compile(
            "^第[零一二三四五六七八九十百千万\\d]+章[\\s：:]*[^\\n]*$",
            Pattern.MULTILINE
    );

    private final Path filePath;
    private final boolean useVirtualThreads;
    private final AtomicInteger processedChapters = new AtomicInteger(0);
    private final ConcurrentHashMap<Integer, Chapter> chapterMap = new ConcurrentHashMap<>();
    private List<ChapterTask> tasks;

    public ChapterSplitter(String filePath, boolean useVirtualThreads) {
        this.filePath = Paths.get(filePath);
        this.useVirtualThreads = useVirtualThreads;
    }

    /**
     * 检查是否支持虚拟线程
     * @return
     */
    public static boolean checkVirtualThreadSupport() {
        try {
            Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
            return true;
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    /**
     * 使用虚拟线程处理章节（Java 21+）
     */
    public List<Chapter> splitWithVirtualThreads() throws IOException, InterruptedException {
        String content = Files.readString(filePath);
        System.out.printf("文件读取完成，总字符数: %,d%n", content.length());

        tasks = findChapterTasks(content);
        System.out.printf("发现 %d 个章节%n", tasks.size());

        Instant start = Instant.now();

        // 方法1: 使用虚拟线程的Executor
        try (ExecutorService executor = createVirtualThreadExecutor()) {
            List<Future<Chapter>> futures = new ArrayList<>();

            for (ChapterTask task : tasks) {
                Future<Chapter> future = executor.submit(() -> processChapter(task));
                futures.add(future);
            }

            // 收集结果
            List<Chapter> chapters = new ArrayList<>();
            for (Future<Chapter> future : futures) {
                try {
                    Chapter chapter = future.get();
                    if (chapter != null) {
                        chapters.add(chapter);
                        chapterMap.put(chapter.getChapterNumber(), chapter);
                    }
                } catch (ExecutionException e) {
                    System.err.printf("处理章节失败: %s%n", e.getCause().getMessage());
                }
            }

            Instant end = Instant.now();
            System.out.printf("所有章节处理完成，耗时: %.2f秒%n",
                    Duration.between(start, end).toMillis() / 1000.0);

            return chapters;
        }
    }

    /**
     * 使用结构化并发（需要Java 21+且启用预览功能）
     * 编译时需添加：--enable-preview
     * 运行时需添加：--enable-preview
     */
    public List<Chapter> splitWithStructuredConcurrency() throws IOException, InterruptedException {
        // 检查是否支持结构化并发
        try {
            Class.forName("java.util.concurrent.StructuredTaskScope");
        } catch (ClassNotFoundException e) {
            System.out.println("当前Java版本不支持StructuredTaskScope，使用替代方案");
            return splitWithVirtualThreads();
        }

        return splitWithStructuredTaskScope();
    }

    private List<Chapter> splitWithStructuredTaskScope() throws IOException, InterruptedException {
        String content = Files.readString(filePath);
        System.out.printf("文件读取完成，总字符数: %,d%n", content.length());

        tasks = findChapterTasks(content);
        System.out.printf("发现 %d 个章节%n", tasks.size());

        Instant start = Instant.now();

        // 使用反射调用StructuredTaskScope，避免编译错误
        try {
            return invokeStructuredTaskScope(tasks);
        } catch (Exception e) {
            System.err.println("结构化并发执行失败，使用传统方式: " + e.getMessage());
            return splitWithTraditionalThreads();
        }
    }

    private List<Chapter> invokeStructuredTaskScope(List<ChapterTask> tasks) throws Exception {
        // 使用反射创建StructuredTaskScope实例
        Class<?> scopeClass = Class.forName("java.util.concurrent.StructuredTaskScope");
        Class<?> shutdownOnFailureClass = Class.forName("java.util.concurrent.StructuredTaskScope$ShutdownOnFailure");

        // 创建StructuredTaskScope实例
        Object scope = scopeClass.getDeclaredConstructor().newInstance();

        List<Future<Chapter>> futures = new ArrayList<>();

        // 提交任务
        for (ChapterTask task : tasks) {
            Callable<Chapter> callable = () -> processChapter(task);

            // 使用反射调用fork方法
            var method = scopeClass.getMethod("fork", Callable.class);
            @SuppressWarnings("unchecked")
            Future<Chapter> future = (Future<Chapter>) method.invoke(scope, callable);
            futures.add(future);
        }

        // 使用反射调用join方法
        var joinMethod = scopeClass.getMethod("join");
        joinMethod.invoke(scope);

        // 使用反射调用throwIfFailed方法
        var throwMethod = scopeClass.getMethod("throwIfFailed");
        throwMethod.invoke(scope);

        // 关闭scope
        var closeMethod = scopeClass.getMethod("close");
        closeMethod.invoke(scope);

        // 收集结果
        List<Chapter> chapters = new ArrayList<>();
        for (Future<Chapter> future : futures) {
            try {
                Chapter chapter = future.get();
                if (chapter != null) {
                    chapters.add(chapter);
                    chapterMap.put(chapter.getChapterNumber(), chapter);
                }
            } catch (ExecutionException e) {
                System.err.printf("处理章节失败: %s%n", e.getCause().getMessage());
            }
        }

        return chapters;
    }

    /**
     * 使用传统线程池处理章节
     */
    public List<Chapter> splitWithThreadPool(int threadCount) throws IOException, InterruptedException {
        String content = Files.readString(filePath);
        System.out.printf("文件读取完成，总字符数: %,d%n", content.length());

        tasks = findChapterTasks(content);
        System.out.printf("发现 %d 个章节%n", tasks.size());

        Instant start = Instant.now();

        try (ExecutorService executor = Executors.newFixedThreadPool(threadCount)) {
            List<CompletableFuture<Chapter>> futures = new ArrayList<>();

            for (ChapterTask task : tasks) {
                CompletableFuture<Chapter> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        return processChapter(task);
                    } catch (Exception e) {
                        System.err.printf("处理章节失败: %s%n", e.getMessage());
                        return null;
                    }
                }, executor);

                futures.add(future);
            }

            // 等待所有任务完成
            CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                    futures.toArray(new CompletableFuture[0])
            );
            allFutures.join();

            Instant end = Instant.now();
            System.out.printf("所有章节处理完成，耗时: %.2f秒%n",
                    Duration.between(start, end).toMillis() / 1000.0);

            // 收集结果
            List<Chapter> chapters = new ArrayList<>();
            for (int i = 0; i < tasks.size(); i++) {
                Chapter chapter = futures.get(i).join();
                if (chapter != null) {
                    chapters.add(chapter);
                    chapterMap.put(chapter.getChapterNumber(), chapter);
                }
            }

            return chapters;
        }
    }

    /**
     * 使用传统线程处理（不使用CompletableFuture）
     */
    public List<Chapter> splitWithTraditionalThreads() throws IOException, InterruptedException {
        String content = Files.readString(filePath);
        System.out.printf("文件读取完成，总字符数: %,d%n", content.length());

        tasks = findChapterTasks(content);
        System.out.printf("发现 %d 个章节%n", tasks.size());

        Instant start = Instant.now();

        ExecutorService executor = getExecutor();
        List<Future<Chapter>> futures = new ArrayList<>();

        for (ChapterTask task : tasks) {
            Future<Chapter> future = executor.submit(() -> processChapter(task));
            futures.add(future);
        }

        // 收集结果
        List<Chapter> chapters = new ArrayList<>();
        for (Future<Chapter> future : futures) {
            try {
                Chapter chapter = future.get();
                if (chapter != null) {
                    chapters.add(chapter);
                    chapterMap.put(chapter.getChapterNumber(), chapter);
                }
            } catch (ExecutionException e) {
                System.err.printf("处理章节失败: %s%n", e.getCause().getMessage());
            }
        }

        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.MINUTES);

        Instant end = Instant.now();
        System.out.printf("所有章节处理完成，耗时: %.2f秒%n",
                Duration.between(start, end).toMillis() / 1000.0);

        return chapters;
    }

    /**
     * 使用并行流处理（最简单的替代方案）
     */
    public List<Chapter> splitWithParallelStream() throws IOException {
        String content = Files.readString(filePath);
        System.out.printf("文件读取完成，总字符数: %,d%n", content.length());

        tasks = findChapterTasks(content);
        System.out.printf("发现 %d 个章节%n", tasks.size());

        Instant start = Instant.now();

        // 使用并行流处理
        List<Chapter> chapters = tasks.parallelStream()
                .map(this::processChapter)
                .filter(chapter -> chapter != null)
                .collect(Collectors.toList());

        // 更新chapterMap
        for (Chapter chapter : chapters) {
            chapterMap.put(chapter.getChapterNumber(), chapter);
        }

        Instant end = Instant.now();
        System.out.printf("所有章节处理完成，耗时: %.2f秒%n",
                Duration.between(start, end).toMillis() / 1000.0);

        return chapters;
    }

    private Chapter processChapter(ChapterTask task) {
        try {
            // 模拟处理工作
            simulateProcessing();

            Chapter chapter = new Chapter(task.title, task.content, task.chapterNumber);

            int processed = processedChapters.incrementAndGet();
            int total = tasks != null ? tasks.size() : 0;

            System.out.printf("[线程: %s] 处理进度: %d/%d - %s%n",
                    getThreadInfo(),
                    processed,
                    total,
                    chapter.getTitle());

            return chapter;
        } catch (Exception e) {
            System.err.printf("处理章节 %s 时出错: %s%n", task.title, e.getMessage());
            return null;
        }
    }

    private void simulateProcessing() {
        try {
            // 模拟处理时间（10-100毫秒）
            Thread.sleep((long) (Math.random() * 90 + 10));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("处理被中断", e);
        }
    }

    private String getThreadInfo() {
        Thread thread = Thread.currentThread();
        if (thread.isVirtual()) {
            return "虚拟线程-" + thread.threadId();
        } else {
            return "平台线程-" + thread.threadId();
        }
    }

    private List<ChapterTask> findChapterTasks(String content) {
        List<ChapterTask> tasks = new ArrayList<>();
        Matcher matcher = CHAPTER_PATTERN.matcher(content);

        int lastEnd = 0;
        int chapterNumber = 1;
        String lastTitle = "前言";

        while (matcher.find()) {
            int start = matcher.start();

            // 获取上一个章节的内容
            if (start > lastEnd) {
                String chapterContent = content.substring(lastEnd, start).trim();
                if (!chapterContent.isEmpty()) {
                    tasks.add(new ChapterTask(lastTitle, chapterContent, chapterNumber));
                    chapterNumber++;
                }
            }

            lastTitle = matcher.group().trim();
            lastEnd = matcher.end();
        }

        // 处理最后一个章节
        if (lastEnd < content.length()) {
            String lastContent = content.substring(lastEnd).trim();
            if (!lastContent.isEmpty()) {
                tasks.add(new ChapterTask(lastTitle, lastContent, chapterNumber));
            }
        }

        return tasks;
    }

    private ExecutorService createVirtualThreadExecutor() {
        if (useVirtualThreads && supportsVirtualThreads()) {
            return Executors.newVirtualThreadPerTaskExecutor();
        } else {
            int cores = Runtime.getRuntime().availableProcessors();
            return Executors.newFixedThreadPool(cores);
        }
    }

    private ExecutorService getExecutor() {
        if (useVirtualThreads && supportsVirtualThreads()) {
            return Executors.newVirtualThreadPerTaskExecutor();
        } else {
            return Executors.newFixedThreadPool(Math.min(tasks.size(), 100));
        }
    }

    private boolean supportsVirtualThreads() {
        try {
            // 检查是否支持虚拟线程
            Executors.class.getMethod("newVirtualThreadPerTaskExecutor");
            return true;
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    public void saveChaptersToFiles(List<Chapter> chapters, String outputDir) throws IOException {
        Path outputPath = Paths.get(outputDir);
        Files.createDirectories(outputPath);

        System.out.println("\n开始保存章节文件...");

        for (Chapter chapter : chapters) {
            String fileName = String.format("chapter_%03d_%s.txt",
                    chapter.getChapterNumber(),
                    sanitizeFileName(chapter.getTitle()));

            Path filePath = outputPath.resolve(fileName);
            String fileContent = String.format("标题: %s%n%n%s",
                    chapter.getTitle(), chapter.getContent());

            Files.writeString(filePath, fileContent);
            System.out.printf("已保存: %s (%,d 字)%n", fileName, chapter.getWordCount());
        }

        System.out.printf("共保存 %d 个章节文件到目录: %s%n", chapters.size(), outputPath.toAbsolutePath());
    }

    private String sanitizeFileName(String title) {
        // 移除文件名中的非法字符
        return title.replaceAll("[\\\\/:*?\"<>|]", "_")
                .replaceAll("\\s+", "_")
                .substring(0, Math.min(title.length(), 50));
    }

    public void printStatistics(List<Chapter> chapters) {
        System.out.println("\n=== 章节统计 ===");
        System.out.printf("总章节数: %d%n", chapters.size());

        int totalWords = chapters.stream().mapToInt(Chapter::getWordCount).sum();
        System.out.printf("总字数: %,d%n", totalWords);

        double avgWords = chapters.stream()
                .mapToInt(Chapter::getWordCount)
                .average()
                .orElse(0);
        System.out.printf("平均每章字数: %.0f%n", avgWords);

        Chapter longest = chapters.stream()
                .max((c1, c2) -> Integer.compare(c1.getWordCount(), c2.getWordCount()))
                .orElse(null);
        Chapter shortest = chapters.stream()
                .min((c1, c2) -> Integer.compare(c1.getWordCount(), c2.getWordCount()))
                .orElse(null);

        if (longest != null) {
            System.out.printf("最长章节: %s (%,d字)%n", longest.getTitle(), longest.getWordCount());
        }
        if (shortest != null) {
            System.out.printf("最短章节: %s (%,d字)%n", shortest.getTitle(), shortest.getWordCount());
        }
    }

    // 内部任务类
    private static class ChapterTask {
        final String title;
        final String content;
        final int chapterNumber;

        ChapterTask(String title, String content, int chapterNumber) {
            this.title = title;
            this.content = content;
            this.chapterNumber = chapterNumber;
        }
    }
}