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

export type TextWrapContext = 'APP' | 'WIDGET';

export type LayoutCandidateLine = {
  /**
   * 该行对应的 token 区间（半开区间），单位与 `breaks` 一致：
   * - start：包含
   * - end：不包含
   */
  start: number;
  end: number;
  /** 该行展示文本（用于 debug；评分以 token/width 为主） */
  text: string;
  /**
   * 该行宽度（同一候选集必须同一单位）。
   * - App：像素等真实测量单位
   * - Widget approx：可使用近似单位（例如 wordCount/graphemeCount）
   */
  width: number | null;
  /** 该行 token 数（EN=词数；TC=grapheme 数） */
  tokenCount: number;
  /** 该行字符簇数（TC 使用；EN 可等于 tokenCount 或 0） */
  charCount: number;
};

export type LayoutCandidate = {
  /** 断点序列（token 边界索引），升序 */
  breaks: number[];
  /** 每行信息（lines.length = breaks.length + 1） */
  lines: LayoutCandidateLine[];
  /** 可选：外部模块（overflow/fallback）可透传的标记 */
  meta?: { overflowed?: boolean; fallback?: boolean };
};

export type ScoreTerm = { key: string; delta: number; detail?: any };

export type ScoreBreakdown = { total: number; terms: ScoreTerm[] };

export type ScoredLayout = {
  score: number;
  flags: { emotionSplit?: boolean; overflowed?: boolean; fallback?: boolean };
  tieKey: Array<number | string>;
  scoreBreakdown?: ScoreBreakdown;
};

export type Weights = Record<string, number>;

export type Lexicons = {
  emotionPhrasesTC: string[];
  emotionPhrasesEN: string[];
  protectedPhrases?: string[];
  shiftWordsTC: string[];
  shiftWordsEN: string[];
  accumWordsTC: string[];
  accumWordsEN: string[];
  selfWordsTC: string[];
  selfWordsEN: string[];
  emotionWordsTC?: string[];
  emotionWordsEN?: string[];
};

export type ScoringConfig = {
  weights: Weights;
  idealWidthRatio: { APP: number; WIDGET: number };
  ellipsisToken: string;
  /** TC 标点集合（用于 PUNCT_BREAK 奖励与行首标点检测） */
  tcPunctuations?: string[];
  /** TC 助词集合（用于 PARTICLE_ISO） */
  tcParticles?: string[];
  /** TC 语尾语助词白名单：触发 PARTICLE_ISO 时惩罚减半 */
  tcParticleWhitelist: string[];
  /** Widow 短词阈值（EN）：len(word) <= widowMaxLen（默认 3） */
  widowMaxLen?: number;
  /** 过短阈值：minPreferred = idealWidth * minPreferredRatio（默认 0.6） */
  minPreferredRatio?: number;
  /** 尾行过短阈值：shortLastLine = idealWidth * shortLastLineRatio（默认 0.5） */
  shortLastLineRatio?: number;
};

export type ScoreLayoutInput = {
  tokens: Token[];
  layoutCandidate: LayoutCandidate;
  lang: Lang;
  context: TextWrapContext;
  /** 可用宽度（同 width 单位），必须由上游提供 */
  availableWidth: number;
  config: ScoringConfig;
  lexicons: Lexicons;
  debug?: boolean;
};

