import type { FontSpec, MeasureWidthImpl } from './types';

/**
 * 默认测量实现（成熟方案）：react-native-text-size
 *
 * 注意：
 * - 该库的 `measure` 是 Promise 异步接口，本模块以 async 方式对齐。
 * - 为避免在测试/Node 环境直接 require `react-native` 造成崩溃，这里使用“延迟加载 + 捕获异常”。
 */

type TextSizeMeasureParams = {
  text: string;
  width?: number;
  fontFamily?: string;
  fontSize?: number;
  fontWeight?: string;
  allowFontScaling?: boolean;
  usePreciseWidth?: boolean;
};

type TextSizeMeasureResult = { width: number };

async function loadReactNativeTextSize(): Promise<{
  measure: (params: TextSizeMeasureParams) => Promise<TextSizeMeasureResult>;
}> {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const mod: any = await import('react-native-text-size');
  return mod?.default ?? mod;
}

function toTextSizeFontSpecs(fontSpec: FontSpec): Pick<TextSizeMeasureParams, 'fontFamily' | 'fontSize' | 'fontWeight'> {
  return {
    fontFamily: fontSpec.fontFamily,
    fontSize: fontSpec.fontSize,
    fontWeight: fontSpec.fontWeight,
  };
}

/**
 * 默认测量函数（可替换/可注入）。
 * - width 约束设为极大值，避免自动换行影响“单行宽度”测量
 * - usePreciseWidth=true，取更精确的宽度（开销更大，但对本算法更稳定）
 */
export const defaultMeasureWidthImpl: MeasureWidthImpl = async ({ text, fontSpec }) => {
  const TextSize = await loadReactNativeTextSize();
  if (!TextSize || typeof TextSize.measure !== 'function') {
    // 典型原因：在 Expo Go 中运行，或没有使用包含该原生模块的 Development Build。
    // 这里抛出更明确的错误，方便上层捕获并在 meta.reason=MEASURE_FAILED 时看到根因。
    throw new Error(
      [
        'react-native-text-size 原生模块不可用：TextSize.measure 不是函数。',
        '请确认你不是在 Expo Go 里运行；需要使用包含该原生模块的 Development Build（expo-dev-client / expo run:ios / EAS dev build）。',
      ].join(' '),
    );
  }
  const res = await TextSize.measure({
    text,
    width: 1_000_000_000,
    usePreciseWidth: true,
    allowFontScaling: true,
    ...toTextSizeFontSpecs(fontSpec),
  });
  return res.width;
};

