/**
 * When several dev servers expose preview URLs, prefer the one that looks like
 * the user-facing web app (monorepo-safe ordering for anatomy + tool listings).
 */

function previewFrontendRank(row: { name: string; command: string }): number {
  const n = row.name.toLowerCase();
  const c = row.command.toLowerCase();
  const blob = `${n} ${c}`;

  if (
    /\bfrontend\b/.test(blob) ||
    blob.includes("/frontend/") ||
    blob.includes("\\frontend\\") ||
    blob.includes("/apps/web") ||
    blob.includes("apps/web/") ||
    blob.includes("/packages/web") ||
    blob.includes("packages/web/")
  ) {
    return 0;
  }

  if (
    blob.includes("next dev") ||
    blob.includes("vite") ||
    blob.includes("nuxt") ||
    blob.includes("remix dev") ||
    blob.includes("astro dev") ||
    blob.includes("npm run dev") ||
    blob.includes("pnpm dev") ||
    blob.includes("yarn dev")
  ) {
    return 1;
  }

  if (/\b(web|ui|client)\b/.test(n)) {
    return 2;
  }

  if (
    /\bapi\b/.test(n) ||
    /\bbackend\b/.test(n) ||
    blob.includes("fastapi") ||
    blob.includes("uvicorn") ||
    blob.includes("gunicorn") ||
    blob.includes("django") ||
    (blob.includes("rails ") && blob.includes("server"))
  ) {
    return 10;
  }

  return 5;
}

function startedAtMs(startedAt: string | Date): number {
  return typeof startedAt === "string"
    ? new Date(startedAt).getTime()
    : startedAt.getTime();
}

export function compareDevPreviewFrontendFirst<
  T extends {
    name: string;
    command: string;
    port: number;
    started_at: string | Date;
  },
>(a: T, b: T): number {
  const pa = previewFrontendRank(a);
  const pb = previewFrontendRank(b);
  if (pa !== pb) return pa - pb;
  const ax = a.port === 3000 ? 0 : a.port;
  const bx = b.port === 3000 ? 0 : b.port;
  if (ax !== bx) return ax - bx;
  return startedAtMs(b.started_at) - startedAtMs(a.started_at);
}

export function sortDevPreviewsFrontendFirst<
  T extends {
    name: string;
    command: string;
    port: number;
    started_at: string | Date;
  },
>(rows: T[]): T[] {
  return [...rows].sort(compareDevPreviewFrontendFirst);
}
