import { NextRequest, NextResponse } from "next/server";

interface HopResult {
  step: number;
  url: string;
  status: number;
  statusText: string;
  location: string | null;
  timing: number;
}

export async function GET(req: NextRequest) {
  let url = req.nextUrl.searchParams.get("url")?.trim();
  if (!url) return NextResponse.json({ error: "url required" }, { status: 400 });

  if (!/^https?:\/\//i.test(url)) url = `https://${url}`;

  const hops: HopResult[] = [];
  const maxRedirects = 15;
  let currentUrl = url;

  try {
    for (let step = 1; step <= maxRedirects; step++) {
      const start = Date.now();
      const res = await fetch(currentUrl, {
        redirect: "manual",
        headers: {
          "User-Agent": "Mozilla/5.0 (compatible; SeaksesTools/1.0)",
        },
        signal: AbortSignal.timeout(10000),
      });
      const timing = Date.now() - start;
      const location = res.headers.get("location");

      hops.push({
        step,
        url: currentUrl,
        status: res.status,
        statusText: res.statusText || statusText(res.status),
        location,
        timing,
      });

      if (res.status >= 300 && res.status < 400 && location) {
        currentUrl = new URL(location, currentUrl).toString();
      } else {
        break;
      }
    }

    return NextResponse.json({ original: url, hops, final: hops[hops.length - 1]?.url });
  } catch (err: unknown) {
    const msg = err instanceof Error ? err.message : "request failed";
    return NextResponse.json({ error: msg, original: url, hops, final: hops[hops.length - 1]?.url ?? url }, { status: 200 });
  }
}

function statusText(code: number): string {
  const map: Record<number, string> = {
    200: "OK", 201: "Created", 204: "No Content",
    301: "Moved Permanently", 302: "Found", 303: "See Other",
    307: "Temporary Redirect", 308: "Permanent Redirect",
    400: "Bad Request", 401: "Unauthorized", 403: "Forbidden",
    404: "Not Found", 429: "Too Many Requests",
    500: "Internal Server Error", 502: "Bad Gateway", 503: "Service Unavailable",
  };
  return map[code] ?? "";
}
