import * as psl from 'psl';

export type IconSource = 'dashboard' | 'domain';

const LOCAL_HOST_SUFFIXES = [
  '.local',
  '.lan',
  '.internal',
  '.home',
  '.localdomain',
] as const;

const IPV4_ADDRESS_PATTERN = /^(\d{1,3}\.){3}\d{1,3}$/;

function normalize(value: string): string {
  return value.trim().toLowerCase();
}

function simplify(value: string): string {
  return normalize(value).replace(/[\s._-]+/g, '');
}

export function generateDashboardIconSlugs(appName: string): string[] {
  const normalizedName = normalize(appName);
  if (!normalizedName) {
    return [];
  }

  const slugs = new Set<string>([
    normalizedName,
    normalizedName.replace(/\s+/g, '-'),
  ]);

  return [...slugs].filter(Boolean);
}

export function isLikelyLocalHostname(hostname: string): boolean {
  const normalizedHostname = normalize(hostname);
  if (!normalizedHostname) {
    return false;
  }

  return (
    normalizedHostname === 'localhost' ||
    IPV4_ADDRESS_PATTERN.test(normalizedHostname) ||
    normalizedHostname.includes(':') ||
    !normalizedHostname.includes('.') ||
    LOCAL_HOST_SUFFIXES.some((suffix) => normalizedHostname.endsWith(suffix))
  );
}

export function shouldPreferDashboardIcons(
  url: string,
  appName: string,
): boolean {
  if (!appName) {
    return false;
  }

  try {
    const hostname = new URL(url).hostname.toLowerCase();
    if (!hostname) {
      return false;
    }

    if (isLikelyLocalHostname(hostname)) {
      return true;
    }

    const parsed = psl.parse(hostname);
    if (!('domain' in parsed) || !parsed.domain) {
      return true;
    }

    const registrableDomain = parsed.domain.toLowerCase();
    if (hostname === registrableDomain) {
      return false;
    }

    const subdomain =
      'subdomain' in parsed && typeof parsed.subdomain === 'string'
        ? parsed.subdomain
        : '';
    if (!subdomain) {
      return false;
    }

    const productLabel = subdomain.split('.').pop() || '';
    const rootLabel = registrableDomain.split('.')[0] || '';
    const normalizedAppName = simplify(appName);

    return (
      normalizedAppName.length > 0 &&
      simplify(productLabel) === normalizedAppName &&
      simplify(rootLabel) !== normalizedAppName
    );
  } catch {
    return false;
  }
}

export function getIconSourcePriority(
  url: string,
  appName: string,
): IconSource[] {
  return shouldPreferDashboardIcons(url, appName)
    ? ['dashboard', 'domain']
    : ['domain', 'dashboard'];
}
