import type { RegistryServer, EnvVar } from './types.js';

function normalizeGitHubUrl(url: string): string {
  return url
    .replace(/^git@github\.com:/, 'https://github.com/')
    .replace(/\.git$/, '')
    .replace(/\/$/, '')
    .toLowerCase();
}

function mergeEnvTemplates(a: EnvVar[], b: EnvVar[]): EnvVar[] {
  const seen = new Map<string, EnvVar>();
  for (const v of a) {
    seen.set(v.name, v);
  }
  for (const v of b) {
    if (!seen.has(v.name)) {
      seen.set(v.name, v);
    }
  }
  return [...seen.values()];
}

export function deduplicateResults(results: RegistryServer[]): RegistryServer[] {
  const byNpm = new Map<string, RegistryServer>();
  const byRepo = new Map<string, RegistryServer>();
  const deduped: RegistryServer[] = [];

  for (const server of results) {
    const npmKey = server.packages.npm;
    const repoKey =
      server.repositoryUrl !== undefined ? normalizeGitHubUrl(server.repositoryUrl) : undefined;

    let existing: RegistryServer | undefined;

    if (npmKey !== undefined) {
      existing = byNpm.get(npmKey);
    }
    if (existing === undefined && repoKey !== undefined) {
      existing = byRepo.get(repoKey);
    }

    if (existing !== undefined) {
      // Merge: keep higher popularity, combine envTemplates
      if (server.popularityScore > existing.popularityScore) {
        const merged: RegistryServer = {
          ...server,
          envTemplate: mergeEnvTemplates(server.envTemplate, existing.envTemplate),
          verified: server.verified || existing.verified,
        };
        // Replace existing in deduped array
        const idx = deduped.indexOf(existing);
        if (idx !== -1) {
          deduped[idx] = merged;
        }
        // Update maps to point to merged
        if (npmKey !== undefined) byNpm.set(npmKey, merged);
        if (repoKey !== undefined) byRepo.set(repoKey, merged);
        if (existing.packages.npm !== undefined) byNpm.set(existing.packages.npm, merged);
        if (existing.repositoryUrl !== undefined) {
          byRepo.set(normalizeGitHubUrl(existing.repositoryUrl), merged);
        }
      } else {
        // Keep existing but merge envTemplates
        existing.envTemplate = mergeEnvTemplates(existing.envTemplate, server.envTemplate);
        existing.verified = existing.verified || server.verified;
      }
    } else {
      deduped.push(server);
      if (npmKey !== undefined) byNpm.set(npmKey, server);
      if (repoKey !== undefined) byRepo.set(repoKey, server);
    }
  }

  return deduped;
}
