function parseHttpOriginHost(originOrReferer: string | undefined): string | null {
  const raw = (originOrReferer || '').trim();
  if (!raw) return null;
  try {
    return new URL(raw).hostname;
  } catch {
    return null;
  }
}

/** พอร์ตจาก ws(s)://host:port — default 7880 */
function liveKitPortFromUrl(wsUrl: string): string {
  try {
    const port = new URL(wsUrl.replace(/^ws(s?):/i, 'http$1:')).port;
    return port || '7880';
  } catch {
    return '7880';
  }
}

function requestPageIsHttps(req?: { get(name: string): string | undefined }): boolean {
  const origin = (req?.get('origin') || req?.get('referer') || '').trim();
  return origin.toLowerCase().startsWith('https://');
}

/** หน้า HTTPS ต้องใช้ wss — และผ่าน reverse proxy มักไม่ใส่ :7880 */
function upgradeWebSocketUrlForHttpsPage(
  wsUrl: string,
  req?: { get(name: string): string | undefined },
): string {
  if (!requestPageIsHttps(req)) {
    return wsUrl;
  }

  let secure = wsUrl.replace(/^ws:\/\//i, 'wss://');
  if (!/^wss:\/\//i.test(secure)) {
    secure = `wss://${secure.replace(/^\/*/, '')}`;
  }

  try {
    const httpLike = secure.replace(/^wss:/i, 'https:');
    const parsed = new URL(httpLike);
  // wss://livekit.example.com:7880 จาก proxy 443 → ตัดพอร์ต 7880
    if (parsed.port === '7880') {
      parsed.port = '';
      return `wss://${parsed.hostname}${parsed.pathname}${parsed.search}`;
    }
    return secure;
  } catch {
    return secure;
  }
}

function isPrivateLanHost(host: string): boolean {
  return (
    host === 'localhost' ||
    host === '127.0.0.1' ||
    /^10\./.test(host) ||
    /^192\.168\./.test(host) ||
    /^172\.(1[6-9]|2\d|3[01])\./.test(host)
  );
}

/**
 * URL WebSocket ที่ browser ใช้
 * - production: LIVEKIT_PUBLIC_URL=wss://livekit.iue.co.th (บังคับใน .env)
 * - dev LAN เท่านั้น: จับ host จาก Origin (ไม่ใช้ exam.* เป็น LiveKit host)
 */
export function resolveLiveKitPublicUrl(req?: {
  get(name: string): string | undefined;
}): string {
  const explicit = (process.env.LIVEKIT_PUBLIC_URL || '').trim();
  if (explicit) {
    return upgradeWebSocketUrlForHttpsPage(explicit, req);
  }

  const defaultUrl = (
    process.env.LIVEKIT_URL ||
    'ws://127.0.0.1:7880'
  ).trim();

  if (!req || process.env.NODE_ENV === 'production') {
    return upgradeWebSocketUrlForHttpsPage(defaultUrl, req);
  }

  const pageHost =
    parseHttpOriginHost(req.get('origin')) ||
    parseHttpOriginHost(req.get('referer'));

  if (!pageHost || !isPrivateLanHost(pageHost)) {
    return upgradeWebSocketUrlForHttpsPage(defaultUrl, req);
  }

  const secure = /^wss:/i.test(defaultUrl) || requestPageIsHttps(req);
  const port = liveKitPortFromUrl(defaultUrl);
  const lanUrl = `ws${secure ? 's' : ''}://${pageHost}:${port}`;
  return upgradeWebSocketUrlForHttpsPage(lanUrl, req);
}

export function getLiveKitConfig() {
  // URL ที่ browser ใช้ connect (host machine) — ค่าเริ่มต้น; token API ใช้ resolveLiveKitPublicUrl
  const url = (
    process.env.LIVEKIT_PUBLIC_URL ||
    process.env.LIVEKIT_URL ||
    'ws://127.0.0.1:7880'
  ).trim();

  // URL ที่ backend ใช้เรียก Room API — ใน Docker ต้องเป็น host.docker.internal
  const serverUrl = (process.env.LIVEKIT_SERVER_URL || url).trim();

  const apiKey = (process.env.LIVEKIT_API_KEY || '').trim();
  const apiSecret = (process.env.LIVEKIT_API_SECRET || '').trim();

  if (!apiKey || !apiSecret) {
    throw new Error(
      'LiveKit is not configured. Set LIVEKIT_API_KEY and LIVEKIT_API_SECRET in backend/.env',
    );
  }

  if (apiKey === apiSecret || apiKey.length > 40) {
    throw new Error(
      'LIVEKIT_API_KEY ต้องเป็นชื่อ key ใน livekit.yaml (เช่น MY_EXAM_API_KEY) ไม่ใช่รหัสลับ xRqox... — ดู backend/.env',
    );
  }

  return { url, serverUrl, apiKey, apiSecret };
}

export function getLiveKitHttpServerHost(): string {
  const { serverUrl } = getLiveKitConfig();
  return serverUrl.replace(/^ws(s?):\/\//, 'http$1://');
}

export function isLiveKitConfigured(): boolean {
  return Boolean(process.env.LIVEKIT_API_KEY && process.env.LIVEKIT_API_SECRET);
}
