import type { Breakpoint } from './types';
import type { Token } from '../core/types';

type TcCandidateConfig = {
  tcPunctuations: string[];
  balanceRange: number;
};

/**
 * 计算 BALANCE 的 idealPos 列表（确定性简化版）。
 *
 * - N=tokens.length
 * - targetLines=min(maxLines,N)
 * - lineIndex in 1..targetLines-1：
 *   idealPos=round(N*lineIndex/targetLines)
 */
export function computeTcIdealPositions(tokens: Token[], maxLines: number): number[] {
  const n = tokens.length;
  const targetLines = Math.max(1, Math.min(maxLines | 0, n));
  const ideals: number[] = [];

  for (let lineIndex = 1; lineIndex <= targetLines - 1; lineIndex++) {
    const idealPos = Math.round((n * lineIndex) / targetLines);
    ideals.push(idealPos);
  }

  // 去重并排序（稳定）
  ideals.sort((a, b) => a - b);
  return ideals.filter((v, idx) => idx === 0 || v !== ideals[idx - 1]);
}

/**
 * TC 候选断点生成：
 * - 标点后：kind=PUNCT，priority=30
 * - 空格后：kind=SPACE，priority=20
 * - BALANCE：kind=BALANCE，priority=5（围绕 idealPos ± balanceRange）
 *
 * 注意：BALANCE 断点允许生成在短语 span 内，是否可用交给评分阶段强惩罚淘汰。
 */
export function generateTcCandidates(tokens: Token[], maxLines: number, config: TcCandidateConfig): { candidates: Breakpoint[]; idealPositions: number[] } {
  const n = tokens.length;
  if (n <= 1) return { candidates: [], idealPositions: [] };

  const punctSet = new Set(config.tcPunctuations);
  const candidates: Breakpoint[] = [];

  // PUNCT / SPACE（扫描 token）
  for (let i = 0; i < n; i++) {
    const t = tokens[i]?.text ?? '';
    const pos = i + 1;

    // 只允许行内断点
    if (pos < 1 || pos > n - 1) continue;

    if (punctSet.has(t)) {
      candidates.push({ pos, kind: 'PUNCT', priority: 30 });
    }

    if (t === ' ') {
      candidates.push({ pos, kind: 'SPACE', priority: 20 });
    }
  }

  // BALANCE
  const idealPositions = computeTcIdealPositions(tokens, maxLines);
  const range = Math.max(0, config.balanceRange | 0);
  if (range > 0 && idealPositions.length > 0) {
    for (const ideal of idealPositions) {
      for (let pos = ideal - range; pos <= ideal + range; pos++) {
        if (pos < 1 || pos > n - 1) continue;
        candidates.push({ pos, kind: 'BALANCE', priority: 5 });
      }
    }
  }

  return { candidates, idealPositions };
}

