const INTERNAL_HOSTNAMES = new Set([
  'api-gateway',
  'sso-core',
  'frontend',
  'docs',
  'media-ws',
  'minio',
  'postgres',
  'redis',
  'rabbitmq',
  'ldap-auth'
]);

export function resolveRegistrableDomain(hostname: string): string {
  const host = hostname.trim().toLowerCase();
  if (!host) return host;
  const labels = host.split('.').filter(Boolean);
  if (labels.length <= 2) return host;
  return `${labels[labels.length - 2]}.${labels[labels.length - 1]}`;
}

export function extractHostnameFromRedirectUri(uri: string): string | null {
  try {
    const parsed = new URL(uri.trim());
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      return null;
    }
    const host = parsed.hostname.trim().toLowerCase();
    return host || null;
  } catch {
    return null;
  }
}

export function isInternalOAuthSslHostname(hostname: string): boolean {
  const host = hostname.trim().toLowerCase();
  if (!host || INTERNAL_HOSTNAMES.has(host)) {
    return true;
  }
  if (/^\d+\.\d+\.\d+\.\d+$/.test(host)) {
    return false;
  }
  return !host.includes('.');
}

export function collectOAuthSslHostnames(redirectUris: string[], excludedHostnames: Iterable<string>): string[] {
  const excluded = new Set(Array.from(excludedHostnames, (item) => item.trim().toLowerCase()).filter(Boolean));
  const result = new Set<string>();

  for (const uri of redirectUris) {
    const host = extractHostnameFromRedirectUri(uri);
    if (!host || excluded.has(host) || isInternalOAuthSslHostname(host)) {
      continue;
    }
    result.add(host);
  }

  return [...result].sort((a, b) => a.localeCompare(b));
}

export function parseHostnameFromPublicUrl(value?: string | null): string | null {
  if (!value?.trim()) return null;
  try {
    return new URL(value.trim()).hostname.toLowerCase();
  } catch {
    return null;
  }
}
