import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { canAccessRoute, parseRoles } from "@/lib/rbac";
import { getRoleRedirectPath } from "@/lib/authTypes";

interface SessionUser {
  id: number | string;
  username: string;
  name: string;
  role: string;
  status?: string;
  [key: string]: any;
}

/**
 * Helper untuk parsing session cookie secara aman.
 * Mengembalikan data user jika valid dan aktif, atau null jika corrupt / nonaktif.
 */
function parseSessionCookie(cookieValue?: string): SessionUser | null {
  if (!cookieValue) return null;
  try {
    const raw = decodeURIComponent(cookieValue);
    const parsed = JSON.parse(raw);
    if (!parsed || !parsed.id || !parsed.role) return null;
    if (parsed.status === "Nonaktif") return null;
    return parsed;
  } catch {
    return null;
  }
}

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

  // 1. Lewati aset statis, font, gambar publik, favicon, dan API auth
  if (
    pathname.startsWith("/_next") ||
    pathname.startsWith("/api/auth") ||
    pathname.startsWith("/images") ||
    pathname.startsWith("/favicon.ico") ||
    pathname.startsWith("/fonts")
  ) {
    return NextResponse.next();
  }

  const rawCookie = request.cookies.get("bpi_session")?.value;
  const sessionUser = parseSessionCookie(rawCookie);

  // 2. Normalisasi rute alias /guru/dashboard -> langsung ke /guru via rewrite
  if (pathname === "/guru/dashboard" || pathname === "/guru/dashboard/") {
    return NextResponse.rewrite(new URL("/guru", request.url));
  }

  // 3. Handler Halaman Login (/login)
  if (pathname === "/login") {
    // Jika sudah ada sesi aktif yang valid, redirect ke landing role
    if (sessionUser) {
      const redirectUrl = getRoleRedirectPath(sessionUser.role);
      const target = redirectUrl && redirectUrl !== "/login" ? redirectUrl : "/";
      const response = NextResponse.redirect(new URL(target, request.url));
      response.headers.set("Cache-Control", "no-store, max-age=0");
      return response;
    }

    // Jika ada sisa cookie tapi corrupt/kadaluarsa/nonaktif, bersihkan cookie
    if (rawCookie && !sessionUser) {
      const response = NextResponse.next();
      response.cookies.delete("bpi_session");
      response.headers.set("Cache-Control", "no-store, max-age=0");
      return response;
    }

    const response = NextResponse.next();
    response.headers.set("Cache-Control", "no-store, max-age=0");
    return response;
  }

  // 4. Handler Jika Sesi Tidak Ada atau Tidak Valid
  if (!sessionUser) {
    // Untuk API endpoints (selain /api/auth), kirim status 401
    if (pathname.startsWith("/api/")) {
      const response = NextResponse.json(
        { success: false, message: "Akses ditolak. Sesi tidak valid atau telah berakhir." },
        { status: 401 }
      );
      if (rawCookie) {
        response.cookies.delete("bpi_session");
      }
      return response;
    }

    // Untuk navigasi halaman: Alihkan HANYA 1x ke /login dan bersihkan cookie lama yang rusak
    const loginUrl = new URL("/login", request.url);
    if (pathname !== "/" && !pathname.startsWith("/login")) {
      loginUrl.searchParams.set("returnUrl", pathname);
    }
    const response = NextResponse.redirect(loginUrl);
    if (rawCookie) {
      response.cookies.delete("bpi_session");
    }
    response.headers.set("Cache-Control", "no-store, max-age=0");
    return response;
  }

  // 5. ATURAN HAK AKSES KHUSUS /guru & SUB-ROUTES (Instruksi 1):
  // Jika session login VALID sebagai Guru/Wali Kelas/Piket/Kurikulum/Super Admin/TU:
  // LANGSUNG izinkan akses tanpa redirect berputar atau lemparan balik ke login.
  if (pathname === "/guru" || pathname.startsWith("/guru/")) {
    const roles = parseRoles(sessionUser.role);
    const isAllowedForGuruPortal = roles.some((r) =>
      [
        "Super Admin",
        "Kurikulum",
        "Guru Mapel",
        "Wali Kelas",
        "Guru Piket",
        "Tata Usaha (TU)",
      ].includes(r)
    );

    if (isAllowedForGuruPortal) {
      const response = NextResponse.next();
      response.headers.set("Cache-Control", "no-store, max-age=0");
      return response;
    }
  }

  // 6. Validasi Hak Akses Role (RBAC) pada URL Terproteksi Lainnya
  if (!pathname.startsWith("/api/")) {
    if (!canAccessRoute(pathname, sessionUser.role)) {
      const fallbackUrl = getRoleRedirectPath(sessionUser.role);

      // PENCEGAHAN REDIRECT LOOP:
      // Jika fallbackUrl sama dengan rute yang sedang diakses, hentikan pengalihan sirkular
      if (fallbackUrl === pathname || fallbackUrl === `${pathname}/`) {
        if (pathname !== "/") {
          const response = NextResponse.redirect(new URL("/", request.url));
          response.headers.set("Cache-Control", "no-store, max-age=0");
          return response;
        }
        return NextResponse.next();
      }

      const response = NextResponse.redirect(new URL(fallbackUrl, request.url));
      response.headers.set("Cache-Control", "no-store, max-age=0");
      return response;
    }
  }

  const response = NextResponse.next();
  response.headers.set("Cache-Control", "no-store, max-age=0");
  return response;
}

export const config = {
  matcher: [
    /*
     * Match all request paths except for:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     * - images (public images)
     */
    "/((?!_next/static|_next/image|favicon.ico|images).*)",
  ],
};
