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.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;

/**
 * Copyright (C), 2015-2025
 * FileName: ChapterSplitterProcessor
 * Author<作者姓名>:   stars
 * CreateTime<创建时间>:   2025/12/16 16:48
 * UpdateTime<修改时间>:   2025/12/16 16:48
 * Description〈功能简述〉: 大文件文章分割处理器
 * History<历史描述>:
 * Since<版本号>: 1.0.0
 */
public class ChapterSplitterProcessor {
    /**
     * 预定义的章节分割模式
     * 中文章节
     */
    public static Pattern getChineseChapterPattern() {
        return Pattern.compile("第[一二三四五六七八九十零百千万0-9]+章\\s*[：:】]?\\s*.+");
    }
    /**
     * 预定义的章节分割模式
     * 英文章节
     */
    public static Pattern getEnglishChapterPattern() {
        return Pattern.compile("CHAPTER\\s+[0-9IVXL]+\\s*[:-]?\\s*.+", Pattern.CASE_INSENSITIVE);
    }
    /**
     * 预定义的章节分割模式
     * 数字章节
     */
    public static Pattern getNumberChapterPattern() {
        return Pattern.compile("^\\d+\\.[\\s\\u3000].+", Pattern.MULTILINE);
    }

    /**
     * 使用虚拟线程拆分章节
     */
    public static List<ChapterContent> splitChaptersWithVirtualThreads(String content) throws IOException {
        // 定义章节分割模式（可根据实际文件格式调整）
        Pattern chapterPattern = getChineseChapterPattern();

        // 查找所有章节标题位置
        List<Integer> chapterStarts = new ArrayList<>();
        var matcher = chapterPattern.matcher(content);
        while (matcher.find()) {
            chapterStarts.add(matcher.start());
        }

        List<ChapterContent> chapters = new ArrayList<>();
        List<CompletableFuture<ChapterContent>> futures = new ArrayList<>();

        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {

            // 为每个章节创建虚拟线程任务
            for (int i = 0; i < chapterStarts.size(); i++) {
                int startIndex = chapterStarts.get(i);
                int endIndex = (i < chapterStarts.size() - 1)
                        ? chapterStarts.get(i + 1)
                        : content.length();
                int chapterNumber = i + 1;

                CompletableFuture<ChapterContent> future = CompletableFuture.supplyAsync(() -> {
                    try {
                        String chapterContent = content.substring(startIndex, endIndex).trim();
                        return new ChapterContent(chapterNumber, extractChapterTitle(chapterContent), chapterContent);
                    } catch (Exception e) {
                        System.err.println("处理章节 " + chapterNumber + " 时出错: " + e.getMessage());
                        return new ChapterContent(chapterNumber, "错误章节", "");
                    }
                }, executor);

                futures.add(future);
            }

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

            // 收集结果
            for (var future : futures) {
                chapters.add(future.join());
            }
        }

        return chapters;
    }

    /**
     * 提取章节标题
     */
    private static String extractChapterTitle(String content) {
        // 取前两行作为标题，或找到第一个换行符
        int firstNewline = content.indexOf('\n');
        if (firstNewline != -1) {
            String title = content.substring(0, Math.min(firstNewline, 100)).trim();
            return title.length() > 50 ? title.substring(0, 50) + "..." : title;
        }
        return content.length() > 50 ? content.substring(0, 50) + "..." : content;
    }

    /**
     * 保存章节到单独的文件
     */
    public static void saveChaptersToFiles(List<ChapterContent> chapters) {
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            List<CompletableFuture<Void>> saveFutures = new ArrayList<>();

            for (ChapterContent chapter : chapters) {
                saveFutures.add(CompletableFuture.runAsync(() -> {
                    try {
                        String fileName = String.format("chapter_%03d.txt", chapter.getNumber());
                        Path outputPath = Paths.get("output", fileName);
                        Files.createDirectories(outputPath.getParent());
                        Files.writeString(outputPath, chapter.getContent());
                        System.out.println("已保存: " + fileName);
                    } catch (IOException e) {
                        System.err.println("保存章节 " + chapter.getNumber() + " 失败: " + e.getMessage());
                    }
                }, executor));
            }

            CompletableFuture.allOf(saveFutures.toArray(new CompletableFuture[0])).join();
        }
    }

    /**
     * 使用虚拟线程处理章节分割的高级方法
     */
    public List<String> splitChapters(String content, Pattern delimiterPattern) {
        ConcurrentLinkedQueue<String> chapters = new ConcurrentLinkedQueue<>();

        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {

            // 找到所有分隔符位置
            var matcher = delimiterPattern.matcher(content);
            List<Integer> positions = matcher.results()
                    .map(MatchResult::start)
                    .toList();

            // 创建并提交所有处理任务
            for (int i = 0; i < positions.size(); i++) {
                final int index = i;
                executor.submit(() -> {
                    int start = positions.get(index);
                    int end = (index < positions.size() - 1)
                            ? positions.get(index + 1)
                            : content.length();

                    String chapter = content.substring(start, end).trim();
                    chapters.add(chapter);

                    // 处理进度提示
                    if (chapters.size() % 10 == 0) {
                        System.out.println(Thread.currentThread() +
                                " 已处理 " + chapters.size() + " 个章节");
                    }
                });
            }
        }

        return chapters.stream().toList();
    }
}