import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { SESSION_COOKIE_NAME } from '@/lib/auth/session-cookie';
import { SESSION_REVOKED_PATH } from '@/lib/constants/logout';

/**
 * 낙관적 체크 전용 — 세션 쿠키의 "존재 여부"만 확인한다. 최종 판단(서명·만료 검증)은
 * lib/auth/dal.ts의 DAL이 담당한다 (Next.js 공식 가이드 지침: Proxy는 느린 조회·최종
 * 인가 판단에 쓰지 않는다).
 *
 * allowlist 방식 — `/login` 외 모든 경로는 세션 쿠키가 없으면 `/login`으로 리다이렉트한다.
 * 신규 라우트를 추가해도 이 목록에 넣지 않는 한 자동으로 보호된다(fail-closed).
 *
 * 위조/만료 쿠키를 가진 채 `/login`에 접근하는 경우의 `/` 리다이렉트는 여기서 하지 않는다 —
 * proxy(`/login`→`/`)와 DAL(`/`→`/login`)이 무한 루프를 이룰 수 있으므로, 그 방향은
 * `/login` 페이지의 `getSessionAdmin()` 검증(서명까지 확인)을 통과했을 때만 수행한다.
 */
// 이슈: `/dev-test/design`은 모든 환경에서 세션 없이 열린다(사용자 요청). 실데이터를 그리지
// 않고 @fox 컴포넌트만 보여주는 화면이지만, 운영에도 노출되는 경로다.
const PUBLIC_PATHS = ['/login', '/dev-test/design', SESSION_REVOKED_PATH];

function isPublicPath(pathname: string): boolean {
  return PUBLIC_PATHS.includes(pathname);
}

export function proxy(request: NextRequest) {
  const { pathname } = request.nextUrl;
  const hasSessionCookie = request.cookies.has(SESSION_COOKIE_NAME);

  if (!isPublicPath(pathname) && !hasSessionCookie) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

/**
 * 정적 자산은 인증 대상이 아니다. 폰트 확장자가 목록에 있어야 하는 이유: `public/fonts`의
 * Pretendard는 `next/font`를 거치지 않아 `/_next/static`이 아닌 `/fonts/*`로 서빙된다 —
 * 빼면 세션 없는 방문자의 폰트 요청이 `/login`으로 리다이렉트돼 로그인 화면만 대체 서체로
 * 그려진다.
 */
/**
 * `contents/upload`(큰 파일 스트리밍 업로드)는 이 목록에서 뺀다.
 *
 * 이슈: 미들웨어를 지나는 요청은 본문이 **10MiB에서 잘린다**(측정: 30MB 전송 → 라우트에
 *   10,485,472바이트만 도달, 미들웨어 제외 시 31,457,478바이트 전부 도달). 잘려도 오류가 아니라
 *   조용히 끝나서 업로드가 "성공한 것처럼" 실패한다. 그동안 Server Action의 한도로 보였던
 *   `Unexpected end of form`도 같은 원인이다.
 *
 * 인증이 느슨해지지 않는다 — 이 파일의 쿠키 확인은 낙관적 체크일 뿐이고 최종 판단은 라우트
 * 핸들러의 `verifySession()`이 한다(파일 상단 주석과 같은 규칙).
 */
export const config = {
  matcher: [
    '/((?!contents/upload|_next/static|_next/image|favicon\\.ico|robots\\.txt|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|woff2|woff|ttf|otf)$).*)',
  ],
};
