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

/**
 * [미들웨어용 세션 업데이트 및 라우트 보호 함수]
 *
 * 이 함수는 모든 페이지 요청이 서버에 도달하기 전에 '가장 먼저' 실행됩니다.
 *
 * 주요 기능:
 * 1. 사용자의 로그인 토큰이 만료되었는지 확인하고, 만료되었다면 자동으로 갱신(Refresh)
 * 2. 인증 상태에 따라 접근 가능한 페이지를 제어 (라우트 보호)
 */
export async function updateSession(request: NextRequest) {
  // 1. 초기 응답 객체를 생성합니다. (그냥 통과시키는 기본 응답)
  let supabaseResponse = NextResponse.next({
    request,
  });

  // 2. 미들웨어 환경에서 동작하는 Supabase 클라이언트를 생성합니다.
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        // 요청(Request)에서 쿠키를 읽어옵니다.
        getAll() {
          return request.cookies.getAll();
        },
        // 쿠키를 저장/수정할 때 사용하는 로직입니다.
        setAll(cookiesToSet) {
          // (1) 요청(Request) 객체에도 쿠키를 업데이트해줍니다. (서버 컴포넌트가 최신 상태를 알도록)
          cookiesToSet.forEach(({ name, value }) =>
            request.cookies.set(name, value),
          );

          // (2) 응답(Response) 객체는 새로 만들어줍니다.
          supabaseResponse = NextResponse.next({
            request,
          });

          // (3) 최종 응답(Response)에 쿠키를 심어서 브라우저로 보냅니다.
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options),
          );
        },
      },
    },
  );

  // 3. [핵심] 사용자의 인증 정보를 가져옵니다.
  // 이 함수를 호출하는 것만으로 Supabase는 만료된 토큰을 자동으로 '재발급(Refresh)' 합니다.
  // 재발급된 쿠키는 위 setAll 로직을 통해 Response에 담겨 브라우저로 전달됩니다.
  const {
    data: { user },
  } = await supabase.auth.getUser();

  console.log(user);
  // 4. [라우트 보호] 인증 상태에 따라 접근 제어
  const { pathname } = request.nextUrl;

  // 4-1. 인증 관련 페이지 목록 (로그인하지 않아도 접근 가능)
  // 로그인, 회원가입, 비밀번호 찾기, 비밀번호 재설정 페이지
  const authPages = [
    "/login",
    "/signup",
    "/forgot-password",
    "/reset-password",
  ];
  const isAuthPage = authPages.some((page) => pathname.startsWith(page));

  // 4-2. 로그인하지 않은 사용자가 보호된 페이지에 접근하려는 경우
  // → /login 페이지로 리다이렉트
  if (!user && !isAuthPage) {
    const loginUrl = new URL("/login", request.url);
    return NextResponse.redirect(loginUrl);
  }

  // 4-3. 이미 로그인한 사용자가 인증 페이지(/login, /signup)에 접근하려는 경우
  // → 메인 페이지(/)로 리다이렉트 (불필요한 접근 방지)
  // 단, /reset-password는 예외 (이메일 링크를 통한 비밀번호 재설정 허용)
  if (user && isAuthPage && pathname !== "/reset-password") {
    const homeUrl = new URL("/", request.url);
    return NextResponse.redirect(homeUrl);
  }

  // 5. 갱신된 쿠키가 담긴 응답을 반환하여 다음 단계(페이지 렌더링)로 넘어갑니다.
  return supabaseResponse;
}
