// 在终稿里定位某条冲突对应的正文区间（供编辑器 setSelectionRange 高亮）。
// 纯逻辑（可单测，不依赖 DOM）。定位优先级：精确 original → where 引号内原文 → 段级 snippet。

import type { ReviewConflict } from "./sse";
import { conflictSnippet } from "./snippet";

export interface DraftRange {
  start: number;
  end: number;
}

// 抽取一段文本里所有成对引号内的内容（「」/“”/‘’/ 直双引号 / 直单引号）。
// where 多形如 草稿中写"<草稿原文>" —— 引号里就是正文精确子串，是最可靠的定位锚。
// 返回去重后按长度降序（长串更具体、误命中概率低）。
const QUOTE_PATTERNS: RegExp[] = [
  /「([^」]{2,})」/g,
  /“([^”]{2,})”/g,
  /"([^"]{2,})"/g,
  /‘([^’]{2,})’/g,
  /'([^']{2,})'/g,
];

export function extractDraftQuotes(where: string): string[] {
  const found = new Set<string>();
  for (const re of QUOTE_PATTERNS) {
    for (const m of where.matchAll(re)) {
      const inner = m[1]?.trim();
      if (inner && inner.length >= 2) found.add(inner);
    }
  }
  return [...found].sort((a, b) => b.length - a.length);
}

// 返回冲突在 text 中的字符区间；定位不到（无 original/引号/段号，或已被改动）→ null。
export function locateInDraft(
  text: string,
  conflict: Pick<ReviewConflict, "original" | "where">,
): DraftRange | null {
  // 1) 精确原文片段（审稿提议的 original）逐字匹配——最可靠。
  if (conflict.original) {
    const idx = text.indexOf(conflict.original);
    if (idx !== -1) {
      return { start: idx, end: idx + conflict.original.length };
    }
  }
  // 2) 从 where 的引号里抽出草稿原文逐字匹配（覆盖 `草稿中写"…"` 这类定位）。
  for (const quote of extractDraftQuotes(conflict.where)) {
    const idx = text.indexOf(quote);
    if (idx !== -1) {
      return { start: idx, end: idx + quote.length };
    }
  }
  // 3) 回退：按 where 段号取段级预览，定位该段。snippet 超长会带省略号，
  //    去掉末尾「…」后用其前缀（仍是该段真实前缀）做 indexOf。
  const snippet = conflictSnippet(text, conflict.where);
  if (snippet) {
    const needle = snippet.endsWith("…") ? snippet.slice(0, -1) : snippet;
    if (needle.length > 0) {
      const idx = text.indexOf(needle);
      if (idx !== -1) {
        return { start: idx, end: idx + needle.length };
      }
    }
  }
  return null;
}
