/**
 * ═══════════════════════════════════════════════════════════
 * 智能分章引擎 · Chapter Engine Service
 * ═══════════════════════════════════════════════════════════
 *
 * 智库节点 Phase 2 · ZY-SVR-006
 * 守护: 铸渊 · ICE-GL-ZY001
 * 版权: 国作登字-2026-A-00037559
 *
 * 功能:
 *   - 识别 TXT 章节分隔规律（正则匹配多种格式）
 *   - 无章节标识时按内容结构分段（空行/字数阈值）
 *   - 输出整齐 TXT + 目录索引 JSON
 *   - 支持重新分章（更新索引）
 *
 * 章节识别规则（优先级从高到低）:
 *   1. 标准格式: "第X章 标题" / "第X回 标题"
 *   2. 数字格式: "Chapter N" / "章节N"
 *   3. 简写格式: "1." / "001" 开头的行
 *   4. 分隔符: "──" / "***" / "===" 等分隔线
 *   5. 兜底: 按空行+字数阈值切分
 *
 * ═══════════════════════════════════════════════════════════
 */

'use strict';

const fs   = require('fs');
const path = require('path');

const BOOKS_DIR    = process.env.BOOKS_DIR    || path.join(__dirname, '..', 'data', 'books');
const CHAPTERS_DIR = process.env.CHAPTERS_DIR || path.join(__dirname, '..', 'data', 'chapters');

// ─── 章节匹配正则 ───
const CHAPTER_PATTERNS = [
  // 第X章/回/节/篇/卷 (支持中文数字和阿拉伯数字)
  /^第[一二三四五六七八九十百千万\d]+[章回节篇卷]\s*.*/,
  // Chapter N / CHAPTER N
  /^[Cc]hapter\s+\d+/,
  // 章节N / 章N
  /^章节?\s*\d+/,
  // 序章/楔子/尾声/番外
  /^(序章|楔子|引子|尾声|番外|后记|前言|附录)\s*/,
  // 纯数字行（如 "001" 或 "1."）
  /^\d{1,4}[.、．]\s*.+/
];

// 分隔符模式
const SEPARATOR_PATTERN = /^[─━═\-\*]{5,}$/;

// 初始化目录
function init() {
  if (!fs.existsSync(CHAPTERS_DIR)) {
    fs.mkdirSync(CHAPTERS_DIR, { recursive: true });
  }
}

/**
 * 验证 ID 安全性（防止路径遍历和原型链污染）
 */
function sanitizeId(id) {
  if (!id || typeof id !== 'string') return null;
  // 禁止原型链污染
  if (id === '__proto__' || id === 'constructor' || id === 'prototype') return null;
  // 禁止路径遍历字符
  if (id.includes('..') || id.includes('/') || id.includes('\\')) return null;
  return id;
}

/**
 * 对一本书进行分章
 * @param {string} filename - 书籍文件名 (在 data/books/ 下)
 * @returns {object} { book_id, title, total_chapters, chapters: [...], toc: [...] }
 */
function splitChapters(filename) {
  if (!sanitizeId(filename)) {
    throw new Error('非法文件名');
  }

  const filePath = path.join(BOOKS_DIR, filename);

  // 防止路径遍历
  const resolvedPath = path.resolve(filePath);
  const resolvedBase = path.resolve(BOOKS_DIR);
  if (!resolvedPath.startsWith(resolvedBase)) {
    throw new Error('非法路径');
  }

  if (!fs.existsSync(filePath)) {
    throw new Error(`书籍文件不存在: ${filename}`);
  }

  const content = fs.readFileSync(filePath, 'utf8');
  const lines   = content.split('\n');

  // 提取书名（文件名或第一行）
  const bookId   = filename.replace('.txt', '');
  const bookMeta = extractBookMeta(lines);

  // 尝试按章节标识分割
  let chapters = splitByPatterns(lines);

  // 如果没有找到章节标识，按分隔符分割
  if (chapters.length <= 1) {
    chapters = splitBySeparators(lines);
  }

  // 如果仍然只有一章，按空行+字数阈值切分
  if (chapters.length <= 1) {
    chapters = splitByParagraphs(lines);
  }

  // 构建目录索引
  const toc = chapters.map((ch, idx) => ({
    index:      idx,
    title:      ch.title,
    start_line: ch.start_line,
    char_count: ch.content.length,
    word_count: ch.content.replace(/\s/g, '').length
  }));

  // 保存分章结果
  const result = {
    book_id:        bookId,
    title:          bookMeta.title || bookId,
    author:         bookMeta.author || '未知',
    total_chapters: chapters.length,
    total_chars:    content.length,
    split_method:   chapters.length > 1 ? detectMethod(chapters) : 'single',
    created_at:     new Date().toISOString(),
    toc,
    chapters:       chapters.map((ch, idx) => ({
      index:   idx,
      title:   ch.title,
      content: ch.content
    }))
  };

  // 保存到 chapters 目录
  const chapterDir = path.join(CHAPTERS_DIR, bookId);
  const resolvedChapterDir = path.resolve(chapterDir);
  const resolvedChaptersBase = path.resolve(CHAPTERS_DIR);
  if (!resolvedChapterDir.startsWith(resolvedChaptersBase)) {
    throw new Error('非法路径');
  }
  if (!fs.existsSync(chapterDir)) {
    fs.mkdirSync(chapterDir, { recursive: true });
  }

  // 保存索引
  const indexFilePath = path.join(chapterDir, 'index.json');
  fs.writeFileSync(
    indexFilePath,
    JSON.stringify({ ...result, chapters: undefined }, null, 2),
    'utf8'
  );

  // 保存每章内容
  for (let i = 0; i < chapters.length; i++) {
    const chFilePath = path.join(chapterDir, `chapter-${String(i).padStart(4, '0')}.txt`);
    fs.writeFileSync(chFilePath, chapters[i].content, 'utf8');
  }

  return result;
}

/**
 * 提取书籍元信息（从前几行）
 */
function extractBookMeta(lines) {
  const meta = { title: '', author: '' };
  const header = lines.slice(0, 10).join('\n');

  // 匹配书名：《xxx》
  const titleMatch = header.match(/《(.+?)》/);
  if (titleMatch) meta.title = titleMatch[1];

  // 匹配作者
  const authorMatch = header.match(/作者[:：]\s*(.+)/);
  if (authorMatch) meta.author = authorMatch[1].trim();

  return meta;
}

/**
 * 按章节正则模式分割
 */
function splitByPatterns(lines) {
  const chapters = [];
  let currentChapter = null;
  let lineNum = 0;

  for (const line of lines) {
    lineNum++;
    const trimmed = line.trim();

    // 检查是否匹配章节模式
    const isChapterHead = CHAPTER_PATTERNS.some(p => p.test(trimmed));

    if (isChapterHead) {
      if (currentChapter) {
        chapters.push(currentChapter);
      }
      currentChapter = {
        title:      trimmed,
        start_line: lineNum,
        content:    ''
      };
    } else if (currentChapter) {
      currentChapter.content += line + '\n';
    }
  }

  if (currentChapter) {
    chapters.push(currentChapter);
  }

  return chapters;
}

/**
 * 按分隔符分割
 */
function splitBySeparators(lines) {
  const chapters = [];
  let currentContent = '';
  let chapterNum = 0;
  let startLine = 1;

  for (let i = 0; i < lines.length; i++) {
    const trimmed = lines[i].trim();

    if (SEPARATOR_PATTERN.test(trimmed) && currentContent.trim().length > 50) {
      chapterNum++;
      chapters.push({
        title:      `段落 ${chapterNum}`,
        start_line: startLine,
        content:    currentContent.trim()
      });
      currentContent = '';
      startLine = i + 2;
    } else {
      currentContent += lines[i] + '\n';
    }
  }

  // 最后一段
  if (currentContent.trim().length > 0) {
    chapterNum++;
    chapters.push({
      title:      `段落 ${chapterNum}`,
      start_line: startLine,
      content:    currentContent.trim()
    });
  }

  return chapters;
}

/**
 * 按空行+字数阈值切分（兜底方案）
 */
function splitByParagraphs(lines, threshold = 3000) {
  const chapters = [];
  let currentContent = '';
  let chapterNum = 0;
  let startLine = 1;
  let consecutiveEmpty = 0;

  for (let i = 0; i < lines.length; i++) {
    const trimmed = lines[i].trim();

    if (trimmed === '') {
      consecutiveEmpty++;
    } else {
      consecutiveEmpty = 0;
    }

    currentContent += lines[i] + '\n';

    // 当连续空行≥2且已超过阈值时切分
    if (consecutiveEmpty >= 2 && currentContent.trim().length >= threshold) {
      chapterNum++;
      chapters.push({
        title:      `自动段落 ${chapterNum}`,
        start_line: startLine,
        content:    currentContent.trim()
      });
      currentContent = '';
      startLine = i + 2;
      consecutiveEmpty = 0;
    }
  }

  // 最后一段
  if (currentContent.trim().length > 0) {
    chapterNum++;
    chapters.push({
      title:      chapters.length === 0 ? '全文' : `自动段落 ${chapterNum}`,
      start_line: startLine,
      content:    currentContent.trim()
    });
  }

  return chapters;
}

/**
 * 检测使用了哪种分割方法
 */
function detectMethod(chapters) {
  if (chapters.length === 0) return 'none';
  const firstTitle = chapters[0].title;
  if (CHAPTER_PATTERNS.some(p => p.test(firstTitle))) return 'pattern';
  if (firstTitle.startsWith('段落')) return 'separator';
  if (firstTitle.startsWith('自动段落')) return 'paragraph';
  return 'mixed';
}

/**
 * 获取已分章的书籍列表
 */
function listChapteredBooks() {
  if (!fs.existsSync(CHAPTERS_DIR)) return [];

  return fs.readdirSync(CHAPTERS_DIR)
    .filter(d => {
      const indexPath = path.join(CHAPTERS_DIR, d, 'index.json');
      return fs.existsSync(indexPath);
    })
    .map(d => {
      const indexPath = path.join(CHAPTERS_DIR, d, 'index.json');
      try {
        return JSON.parse(fs.readFileSync(indexPath, 'utf8'));
      } catch {
        return null;
      }
    })
    .filter(Boolean);
}

/**
 * 获取某本书的分章详情
 */
function getBookChapters(bookId) {
  if (!sanitizeId(bookId)) return null;
  const indexPath = path.join(CHAPTERS_DIR, bookId, 'index.json');
  const resolvedPath = path.resolve(indexPath);
  const resolvedBase = path.resolve(CHAPTERS_DIR);
  if (!resolvedPath.startsWith(resolvedBase)) return null;
  if (!fs.existsSync(indexPath)) return null;

  try {
    return JSON.parse(fs.readFileSync(indexPath, 'utf8'));
  } catch {
    return null;
  }
}

/**
 * 获取某章内容
 */
function getChapterContent(bookId, chapterIndex) {
  if (!sanitizeId(bookId)) return null;
  const chapterPath = path.join(
    CHAPTERS_DIR,
    bookId,
    `chapter-${String(chapterIndex).padStart(4, '0')}.txt`
  );

  // 防止路径遍历
  const resolvedPath = path.resolve(chapterPath);
  const resolvedBase = path.resolve(CHAPTERS_DIR);
  if (!resolvedPath.startsWith(resolvedBase)) return null;

  if (!fs.existsSync(chapterPath)) return null;

  return fs.readFileSync(chapterPath, 'utf8');
}

/**
 * 获取分章引擎统计
 */
function getStats() {
  const books = listChapteredBooks();
  return {
    total_chaptered_books: books.length,
    total_chapters:        books.reduce((sum, b) => sum + (b.total_chapters || 0), 0),
    total_chars:           books.reduce((sum, b) => sum + (b.total_chars || 0), 0),
    methods: {
      pattern:   books.filter(b => b.split_method === 'pattern').length,
      separator: books.filter(b => b.split_method === 'separator').length,
      paragraph: books.filter(b => b.split_method === 'paragraph').length
    }
  };
}

// 初始化
init();

module.exports = {
  splitChapters,
  listChapteredBooks,
  getBookChapters,
  getChapterContent,
  getStats,
  CHAPTER_PATTERNS
};
