import { NextRequest, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";

const publicPaths = [
  "/welcome",
  "/features",
  "/pricing",
  "/privacy",
  "/terms",
  "/login",
  "/signup",
  "/invite",
  "/forgot-password",
  "/reset-password",
  "/setup",
  "/s",
  "/api/auth",
  "/api/health",
  "/api/setup",
  "/api/onboarding",
  "/api/invitations/verify",
  "/api/survey/submit",
  "/api/jobs/process",
  "/api/email-watch/poll",
  "/api/ftp-watch/poll",
];

const workspaceSetupExemptPaths = [
  "/workspace-setup",
  "/onboarding",
  "/api/onboarding",
  "/api/org/create-personal",
  "/api/org/list",
  "/api/auth",
];

const onboardingExemptPaths = [
  "/onboarding",
  "/api/onboarding",
  "/api/auth",
];

function isPublic(pathname: string) {
  return publicPaths.some(
    (p) => pathname === p || pathname.startsWith(p + "/")
  );
}

function isOnboardingExempt(pathname: string) {
  return onboardingExemptPaths.some(
    (p) => pathname === p || pathname.startsWith(p + "/")
  );
}

export async function middleware(req: NextRequest) {
  const { pathname } = req.nextUrl;

  const isStaticFile = pathname.startsWith("/_next/") ||
    pathname.startsWith("/favicon") ||
    /^\/(.*\.(ico|svg|png|jpg|jpeg|gif|webp|woff2?|ttf|css|js|map))$/.test(pathname);
  if (isStaticFile) {
    return NextResponse.next();
  }

  if (isPublic(pathname)) {
    return NextResponse.next();
  }

  const secureCookie =
    req.headers.get("x-forwarded-proto") === "https" ||
    req.nextUrl.protocol === "https:";
  const token = await getToken({
    req,
    secret: process.env.AUTH_SECRET,
    secureCookie,
  });

  if (!token) {
    if (pathname === "/login" || pathname === "/signup") {
      return NextResponse.next();
    }
    const welcomeUrl = new URL("/welcome", req.url);
    return NextResponse.redirect(welcomeUrl);
  }

  const hasOrg = !!token.orgId;
  const onboardingDone = token.onboardingComplete === true;

  function isWorkspaceSetupExempt(p: string) {
    return workspaceSetupExemptPaths.some(
      (x) => p === x || p.startsWith(x + "/")
    );
  }

  if (!hasOrg && !isWorkspaceSetupExempt(pathname)) {
    return NextResponse.redirect(new URL("/workspace-setup", req.url));
  }

  if (hasOrg && !onboardingDone && !isOnboardingExempt(pathname)) {
    return NextResponse.redirect(new URL("/onboarding", req.url));
  }

  const role =
    (typeof token.orgRole === "string" && token.orgRole) ||
    (typeof token.role === "string" && token.role) ||
    "viewer";
  const isAdminOrOwner = role === "admin" || role === "owner";

  if (pathname.startsWith("/settings") && !isAdminOrOwner) {
    const url = new URL("/", req.url);
    url.searchParams.set("error", "forbidden");
    return NextResponse.redirect(url);
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
