// frontend/lib/auth.ts — phase-15 인증 클라이언트 헬퍼.
// 데모 무손상: 이 모듈은 호출되기 전엔 부작용이 없다. 게이트는 proxy.ts(미들웨어)가 담당.
import type { Me } from "@/lib/types";

const BASE = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:31800";
const AUTH_ENABLED = process.env.NEXT_PUBLIC_AUTH_ENABLED === "true";

/** 로그인. 성공 시 MeOut, 실패(401)면 에러를 던진다(쿠키는 백엔드 Set-Cookie). */
export async function login(email: string, password: string): Promise<Me> {
  const res = await fetch(`${BASE}/api/auth/login`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({ email, password }),
  });
  if (!res.ok) {
    throw new Error("이메일 또는 비밀번호가 올바르지 않아요");
  }
  return res.json() as Promise<Me>;
}

/** 로그아웃. 쿠키를 비운다. 실패해도 조용히 무시(이미 로그아웃 상태일 수 있음). */
export async function logout(): Promise<void> {
  try {
    await fetch(`${BASE}/api/auth/logout`, {
      method: "POST",
      credentials: "include",
    });
  } catch {
    // 네트워크 오류는 무시 — UI는 로그인 화면으로 전이하면 충분.
  }
}

/** 현재 사용자. 세션 없으면(401) null. */
export async function getMe(signal?: AbortSignal): Promise<Me | null> {
  const res = await fetch(`${BASE}/api/me`, {
    credentials: "include",
    cache: "no-store",
    signal,
  });
  if (res.status === 401) return null;
  if (!res.ok) return null;
  return res.json() as Promise<Me>;
}

/**
 * 인증 켜짐일 때만 동작하는 얇은 fetch 래퍼. 401이면 /login?next=<현재경로>로 보낸다.
 * 데모(AUTH_ENABLED=false)에선 일반 fetch와 동일 — 부작용 없음.
 * 중앙 래퍼가 없으므로 전 호출을 개조하지 않는다(라우트 보호는 proxy.ts가 담당, 이건 보조).
 */
export async function apiFetch(input: string, init?: RequestInit): Promise<Response> {
  const url = input.startsWith("http")
    ? input
    : `${BASE}${input.startsWith("/") ? "" : "/"}${input}`;
  const res = await fetch(url, { credentials: "include", ...init });
  if (AUTH_ENABLED && res.status === 401 && typeof window !== "undefined") {
    const next = window.location.pathname + window.location.search;
    window.location.assign(`/login?next=${encodeURIComponent(next)}`);
  }
  return res;
}
