import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { verifyAdminSession, COOKIE_NAME_ADMIN } from "@/lib/admin-session";

const isProtectedRoute = createRouteMatcher(["/dashboard(.*)", "/onboarding(.*)", "/api/publish(.*)", "/api/upload(.*)", "/api/user(.*)"]);

function isAdminRoute(pathname: string): boolean {
  return pathname.startsWith("/admin") || pathname.startsWith("/api/admin");
}

function getSubdomain(req: NextRequest): string | null {
  const host = req.headers.get("host");
  if (!host) return null;

  const apex = process.env.NEXT_PUBLIC_APP_DOMAIN || "testbed.mk";
  const portIndex = host.indexOf(":");
  const hostname = portIndex !== -1 ? host.slice(0, portIndex) : host;

  const reserved = ["www", "coolify", "mail", "accounts", "clerk", "clk", "clk2", "clkmail"];

  if (hostname === apex || reserved.includes(hostname) || hostname === `www.${apex}`) return null;

  if (hostname.endsWith(`.${apex}`)) {
    const sub = hostname.slice(0, hostname.length - apex.length - 1);
    if (sub && !reserved.includes(sub)) return sub;
  }

  return null;
}

export default clerkMiddleware(async (auth, req: NextRequest) => {
  if (isAdminRoute(req.nextUrl.pathname)) {
    if (req.nextUrl.pathname === "/admin/login" || req.nextUrl.pathname === "/api/admin/login") {
      return NextResponse.next();
    }

    const token = req.cookies.get(COOKIE_NAME_ADMIN)?.value;
    if (!token || !(await verifyAdminSession(token))) {
      if (req.nextUrl.pathname.startsWith("/api/")) {
        return NextResponse.json({ error: "Неавторизирано" }, { status: 401 });
      }
      return NextResponse.redirect(new URL("/admin/login", req.url));
    }

    return NextResponse.next();
  }

  if (isProtectedRoute(req)) {
    await auth.protect();
  }

  const subdomain = getSubdomain(req);
  if (subdomain && !req.nextUrl.pathname.startsWith("/api")) {
    const url = req.nextUrl.clone();
    url.pathname = `/${subdomain}${url.pathname === "/" ? "" : url.pathname}`;
    return NextResponse.rewrite(url);
  }

  return NextResponse.next();
});

export const config = {
  matcher: ["/(api|trpc)(.*)", "/__clerk/:path*", "/((?!_next|api/static|.*\\..*).*)"],
};
