export function redactText(value: string): string {
  return value
    .replace(/1[3-9]\d{9}/g, '[PHONE]')
    .replace(/\b\d{17}[\dXx]\b/g, '[ID_CARD]')
    .replace(/Bearer\s+[A-Za-z0-9._~+/-]+=*/gi, 'Bearer [REDACTED]')
    .replace(/(sk-|api[_-]?key["'=:\s]+)[A-Za-z0-9._-]{8,}/gi, '$1[REDACTED]');
}

export function makeRedactingReplacer(redact: (value: string) => string) {
  return (key: string, value: unknown): unknown => {
    if (/password|token|secret|api.?key|authorization|phone|mobile|id.?card|身份证/i.test(key)) {
      return '[REDACTED]';
    }
    if (typeof value === 'string') return redact(value);
    return value;
  };
}

export function parseToolArguments(value: string): unknown {
  try {
    return JSON.parse(value || '{}') as unknown;
  } catch {
    return null;
  }
}

export function safeToolName(name: string): string {
  return name.replace(/[^a-zA-Z0-9_]/g, '_').slice(0, 64) || '_invalid';
}

export function throwIfAborted(signal: AbortSignal): void {
  if (signal.aborted) throw signal.reason ?? new Error('aborted');
}

export function errorCode(error: unknown): string {
  if (error && typeof error === 'object' && 'status' in error) {
    const status = Number(error.status);
    if (status === 408) return 'UPSTREAM_TIMEOUT';
    if (status >= 400 && status < 500) return 'UPSTREAM_REQUEST_ERROR';
  }
  return 'UPSTREAM_ERROR';
}

export function assertGeneratedLength(reasoning: string, content: string): void {
  if (reasoning.length + content.length > 256 * 1024) {
    throw new Error('AI response exceeded limit');
  }
}
