import 'server-only';
import { cache } from 'react';
import { redirect } from 'next/navigation';
import { readSessionToken } from '@/lib/auth/session';
import { verifySessionToken } from '@/lib/auth/session-token';
import type { AdminUser } from '@/lib/domain/admin-user';

/**
 * 공식 가이드의 Data Access Layer(DAL) — 인증·인가 판단을 이 파일에 집중시킨다.
 * `cache()`로 렌더 패스당 세션 조회를 1회로 dedupe한다.
 *
 * 이후 모든 mutation(Server Action)은 Repository를 직접 호출하기 전에 반드시
 * `verifySession()`(또는 `getSessionAdmin()`)을 거쳐야 한다 — Server Action은 UI를 거치지 않고
 * 직접 호출될 수 있으므로 이 검증이 유일한 최종 방어선이다.
 *
 * 백엔드에 관리자 프로필 조회 API가 없어(2026-08 기준) 세션 payload에 이미 실려 있는 클레임
 * (adminId/loginId/admRoleCd)만으로 AdminUser를 구성한다 — Repository 왕복이 없다.
 */

/** 세션 검증 결과를 null 허용으로 반환 — redirect 없이 상태만 알고 싶을 때 사용 (예: 로그인 페이지). */
export const getSessionAdmin = cache(async (): Promise<AdminUser | null> => {
  const token = await readSessionToken();
  if (!token) {
    return null;
  }

  const session = verifySessionToken(token);
  if (!session) {
    return null;
  }

  return {
    id: session.adminId,
    // 백엔드 accessToken에 관리자 이름 클레임이 없어 loginId로 대체한다(사용자 확정 사항).
    name: session.loginId,
    loginId: session.loginId,
    roleCode: session.admRoleCd,
  };
});

/** 보호 라우트·Server Action 진입점 — 세션이 없으면 `/login`으로 redirect한다. */
export async function verifySession(): Promise<AdminUser> {
  const admin = await getSessionAdmin();
  if (!admin) {
    redirect('/login');
  }

  return admin;
}
