import { NextRequest, NextResponse } from 'next/server';
import { getSession } from '@/lib/auth';

type Result = { name: string; exists: boolean | null; versionOk?: boolean; latest?: string };

const TIMEOUT_MS = 6000;

async function fetchJson(url: string): Promise<any | null> {
  const ctrl = new AbortController();
  const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS);
  try {
    const res = await fetch(url, { headers: { Accept: 'application/json' }, signal: ctrl.signal });
    if (!res.ok) return null;
    return await res.json();
  } catch {
    return null;
  } finally {
    clearTimeout(timer);
  }
}

async function checkNpm(name: string, version?: string): Promise<Result> {
  const data = await fetchJson(`https://registry.npmjs.org/${encodeURIComponent(name)}`);
  if (!data) return { name, exists: false };
  const versions = data.versions && typeof data.versions === 'object' ? Object.keys(data.versions) : [];
  const latest = data['dist-tags']?.latest;
  const clean = (version ?? '').replace(/^[\^~>=<\s]+/, '').trim();
  const versionOk = !clean || clean === 'latest' || versions.includes(clean);
  return { name, exists: true, versionOk, latest };
}

async function checkMaven(name: string): Promise<Result> {
  // Accept "groupId:artifactId" or a bare artifactId.
  const [g, a] = name.includes(':') ? name.split(':') : [undefined, name];
  const q = g ? `g:"${g}" AND a:"${a}"` : `a:"${a}"`;
  const data = await fetchJson(`https://search.maven.org/solrsearch/select?q=${encodeURIComponent(q)}&rows=1&wt=json`);
  if (!data) return { name, exists: false };
  const found = (data.response?.numFound ?? 0) > 0;
  return { name, exists: found, versionOk: true, latest: data.response?.docs?.[0]?.latestVersion };
}

/**
 * POST /api/registry/validate
 * Body: { ecosystem: 'npm' | 'maven', items: { name: string; version?: string }[] }
 * Checks whether the proposed target packages actually exist in the public registry,
 * so the UI can clear the "verify" flag on confirmed entries. Best-effort, bounded.
 */
export async function POST(request: NextRequest) {
  const session = await getSession(request.cookies.get('scriba.access_token')?.value);
  if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });

  const body = await request.json().catch(() => ({} as Record<string, unknown>));
  const ecosystem = (body as { ecosystem?: string }).ecosystem;
  const rawItems = Array.isArray((body as { items?: unknown }).items) ? (body as { items: unknown[] }).items : [];
  const items = rawItems
    .slice(0, 60)
    .map((it) => (it && typeof it === 'object' ? { name: String((it as any).name ?? '').trim(), version: String((it as any).version ?? '').trim() } : null))
    .filter((it): it is { name: string; version: string } => !!it && it.name.length > 0);

  if (ecosystem !== 'npm' && ecosystem !== 'maven') {
    // Unsupported ecosystem — report unknown so the caller leaves entries as-is.
    return NextResponse.json({ results: items.map((it) => ({ name: it.name, exists: null })) });
  }

  const results = await Promise.all(
    items.map((it) => (ecosystem === 'npm' ? checkNpm(it.name, it.version) : checkMaven(it.name))),
  );
  return NextResponse.json({ results });
}
