import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

/**
 * Middleware function to handle Supabase authentication and session management
 * Validates user sessions, handles redirects, and manages authentication state
 * 
 * @param request - Next.js request object
 * @returns Promise resolving to NextResponse with authentication handling
 * 
 * @example
 * // In middleware.ts
 * export async function middleware(request: NextRequest) {
 *   return await updateSession(request);
 * }
 */
export async function updateSession(request: NextRequest) {
  const pathname = request.nextUrl.pathname;

  // Pass pathname to downstream server components via request header.
  // Used by the authenticated layout to allow signup pages without a session.
  request.headers.set('x-pathname', pathname);

  let supabaseResponse = NextResponse.next({
    request,
  });

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll().map(cookie => {
            if (cookie.name.includes("-auth-token") && cookie.value) {
              let rawValue = cookie.value.trim();
              if (rawValue.startsWith('"%22') || rawValue.startsWith('%22')) {
                rawValue = decodeURIComponent(rawValue);
              }
              if (rawValue.startsWith('"') && rawValue.endsWith('"')) {
                rawValue = rawValue.slice(1, -1);
              }
              if (rawValue.startsWith("eyJ")) {
                return {
                  ...cookie,
                  value: JSON.stringify({
                    access_token: rawValue,
                    refresh_token: "", // Mock refresh token to prevent crash
                    user: {} // Mock user object so property assignment doesn't throw
                  })
                };
              }
            }
            return cookie;
          });
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value }) =>
            request.cookies.set(name, value)
          );
          supabaseResponse = NextResponse.next({
            request,
          });
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          );
        },
      },
    }
  );

  // Use getUser() — the only safe server-side auth check (validates JWT with Supabase).
  // Do NOT use getSession() here — it reads unverified cookie data.
  const {
    data: { user },
  } = await supabase.auth.getUser();

  // Route classification
  const protectedPaths = ["/dashboard", "/contractor", "/worker", "/messages", "/profile", "/notifications", "/rate", "/ratings"];
  const isProtected = protectedPaths.some((p) => pathname.startsWith(p));
  const isSignup = pathname.includes("/signup");
  const isVerifyPage = pathname === "/auth/verify-email";
  const isAuthPage = pathname.startsWith("/auth/login") || pathname.startsWith("/auth/signup") || pathname.startsWith("/auth/forgot-password") || pathname.startsWith("/auth/reset-password");

  // ── Not logged in ──
  if (!user) {
    // Redirect unauthenticated users away from protected routes (but allow signup pages)
    if (isProtected && !isSignup) {
      const url = request.nextUrl.clone();
      url.pathname = "/auth/login";
      return NextResponse.redirect(url);
    }
    return supabaseResponse;
  }

  // ── Logged in ──
  const emailVerified = !!user.email_confirmed_at;

  if (!emailVerified) {
    // Unverified user trying to access protected routes → send to verify page
    // (but let them stay on signup flows to finish onboarding after verification)
    if (isProtected && !isSignup && !isVerifyPage) {
      const url = request.nextUrl.clone();
      url.pathname = "/auth/verify-email";
      return NextResponse.redirect(url);
    }
  } else {
    // Verified user on auth pages → send to dashboard
    if (isAuthPage || isVerifyPage) {
      const url = request.nextUrl.clone();
      url.pathname = "/dashboard";
      return NextResponse.redirect(url);
    }
  }

  return supabaseResponse;
}
