import type { Token } from '../core/types';
import type { Breakpoint } from '../breakpoints/types';
import type { ContextProfile, FontSpec, MeasureWidthImpl } from '../measure/types';
import type { Lexicons, ScoringConfig, ScoreTerm } from '../scoring/types';

export type WidthMode = 'MEASURE' | 'APPROX';

export type SearchWidgetConfig = {
  beamK: number;
  expandM: number;
  tooLongThresholds: { EN: number; TC: number };
};

export type SearchWidgetMeasureInput =
  | { widthMode: 'APPROX' }
  | {
      widthMode: 'MEASURE';
      contextProfile: ContextProfile;
      fontSpec: Partial<FontSpec> | null | undefined;
      measureWidthImpl?: MeasureWidthImpl;
      /** Widget 是否启用测量；默认 true（本模块仅在明确 MEASURE 时开启） */
      widgetEnableMeasure?: boolean;
    };

export type SearchWidgetScoringInput = {
  config: ScoringConfig;
  lexicons: Lexicons;
  debug?: boolean;
};

export type SearchWidgetInput = {
  tokens: Token[];
  lang: 'TC' | 'EN';
  breakpoints: Breakpoint[];
  /**
   * 可用宽度（与 line.width 的单位必须一致）：
   * - MEASURE：像素等真实测量单位
   * - APPROX：建议用“近似单位”（例如每行可容纳的 token 数）
   */
  availableWidth: number;
  maxLines: number;
  context: 'WIDGET';
  measure: SearchWidgetMeasureInput;
  scoring: SearchWidgetScoringInput;
  config?: Partial<SearchWidgetConfig>;
};

export type WidgetLayoutMeta = {
  breaks: number[];
  scoreTopTerms?: ScoreTerm[];
  score?: number;
  /**
   * 仅当进入 approx/降级时填入，便于 integration/打点模块统一处理：
   * - WIDTH_UNKNOWN：未启用测量或测量能力缺失
   * - MEASURE_FAILED：测量抛错或返回非法
   */
  reason?: 'WIDTH_UNKNOWN' | 'MEASURE_FAILED';
};

export type BestWidgetLayout = {
  breaks: number[];
  lines: string[];
  wrappedText: string;
  meta?: WidgetLayoutMeta;
};

export type SearchWidgetFailureReason = 'TOO_LONG' | 'NO_CANDIDATE';

export type SearchWidgetResult =
  | { ok: true; bestLayout: BestWidgetLayout }
  | { ok: false; reason: SearchWidgetFailureReason; meta?: { tokenCount: number } };

export type WidgetBeam = {
  pos: number;
  breaks: number[];
  lines: Array<{
    start: number;
    end: number;
    text: string;
    width: number;
    tokenCount: number;
    charCount: number;
    /** 该行是否为近似宽度（用于 meta.reason） */
    isApprox: boolean;
    approxReason?: 'WIDTH_UNKNOWN' | 'MEASURE_FAILED';
  }>;
  score: number;
  tieKey: number[];
  scoreTopTerms?: ScoreTerm[];
};

