/**
 * Sentry 面包屑脱敏 —— PAC 是医疗系统,fetch/xhr 面包屑的 URL 常带患者标识
 * (patientId / medicalRecordNumber / externalId / tenant/clinic id 等)。
 * 直接上报会把 PII 落进 Sentry;整段被服务端打成 [Filtered] 又看不出调的哪个接口。
 * 折中:客户端先把 URL 归一化 —— 路由形状保留、真实 id 换成 :id、query 整段丢。
 *   GET https://host/pac/v1/plans/<uuid>/full?x=1  →  GET https://host/pac/v1/plans/:id/full
 */
import type { Breadcrumb } from '@sentry/nextjs';

/** 一个路径段是否"像 id"(UUID / 纯数字 / 长 hex / 病历号样式)→ 该被 :id 替换。 */
function looksLikeId(seg: string): boolean {
  if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(seg)) return true; // uuid
  if (/^\d{3,}$/.test(seg)) return true; // 纯数字 id(如 1930118)
  if (/^[0-9a-f]{16,}$/i.test(seg)) return true; // 长 hex(tenant/org/clinic id 等 32 位)
  if (/[A-Za-z].*\d{4,}|\d{4,}.*[A-Za-z]/.test(seg)) return true; // 字母+4位以上数字混合(病历号 ZJ0A034947)
  return false;
}

/** 归一化 URL:段级 id → :id,query 全去掉;解析失败退回只砍 query。 */
export function sanitizeUrl(url: string): string {
  try {
    const u = new URL(url, 'http://_'); // 提供 base 以支持相对 URL
    const path = u.pathname
      .split('/')
      .map((seg) => (seg && looksLikeId(seg) ? ':id' : seg))
      .join('/');
    const origin = u.origin && u.origin !== 'http://_' ? u.origin : ''; // 相对 URL 的假 base 不带出
    return origin + path;
  } catch {
    return url.split('?')[0] ?? url;
  }
}

/** beforeBreadcrumb 入口:只处理网络类面包屑的 URL,其余原样返回。 */
export function scrubBreadcrumb(breadcrumb: Breadcrumb): Breadcrumb {
  const cat = breadcrumb.category;
  if ((cat === 'fetch' || cat === 'xhr') && breadcrumb.data && typeof breadcrumb.data.url === 'string') {
    breadcrumb.data.url = sanitizeUrl(breadcrumb.data.url);
  }
  return breadcrumb;
}
