import type { FontSpec } from './types';
import { MissingFontSpecError, buildMissingFontSpecMessage } from './errors';

/**
 * 校验 fontSpec 必填字段。
 * 约束：缺失字段必须报错（简体中文），避免跨端漂移。
 */
export function assertFontSpecComplete(fontSpec: Partial<FontSpec> | undefined | null): asserts fontSpec is FontSpec {
  if (!fontSpec) {
    throw new MissingFontSpecError(buildMissingFontSpecMessage(['fontFamily', 'fontWeight', 'fontSize']));
  }

  const missing: string[] = [];
  if (!fontSpec.fontFamily) missing.push('fontFamily');
  if (!fontSpec.fontWeight) missing.push('fontWeight');
  if (fontSpec.fontSize === undefined || fontSpec.fontSize === null) missing.push('fontSize');

  if (missing.length) throw new MissingFontSpecError(buildMissingFontSpecMessage(missing));
  if (!Number.isFinite(fontSpec.fontSize)) {
    throw new MissingFontSpecError('fontSpec.fontSize 必须是有限数值（number）。请检查调用 wrapText() 时传入的 fontSize。');
  }
}

/**
 * 生成 fontSpecKey（确定性）。
 * 规则：`fontFamily|fontWeight|fontSize`（顺序固定）
 */
export function buildFontSpecKey(fontSpec: Partial<FontSpec> | undefined | null): string {
  assertFontSpecComplete(fontSpec);
  return `${fontSpec.fontFamily}|${fontSpec.fontWeight}|${String(fontSpec.fontSize)}`;
}

