'use client';

import { useEffect, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { useFeedback } from '@/app/_hooks/use-feedback';

interface LogoutNoticeProps {
  /** 로그아웃 Server Action이 백엔드 호출 실패를 알리려고 실어 보낸 쿼리 파라미터가 있었는가. */
  showError: boolean;
}

const LOGOUT_ERROR_MESSAGE =
  '로그아웃 처리 중 일부 오류가 있었지만 로그아웃되었습니다.';

/**
 * 화면에 그릴 UI가 없는 알림 트리거 컴포넌트 — `app/(protected)/_actions.ts`의 `logout()`이
 * 백엔드 로그아웃 호출 실패를 알리려고 `/login`에 실어 보낸 쿼리 파라미터를 Page(Server
 * Component)가 읽어 `showError`로 넘겨주면, 마운트 시 1회 토스트로 보여준다.
 *
 * Server Action은 redirect() 이후 클라이언트에 값을 돌려줄 방법이 없다(redirect가 즉시
 * 던져짐) — 그래서 이 화면에 도착해 마운트된 뒤(=redirect가 끝난 뒤)에만 알릴 수 있다. 이
 * 컴포넌트는 오직 이 시점에만 반응하므로 redirect와 토스트 표시가 시점상 겹치지 않는다.
 *
 * 표시 후에는 쿼리 파라미터를 제거한다(router.replace) — 새로고침·북마크 재방문 시 지난 실패가
 * 다시 뜨는 것을 막는다.
 *
 * `hasNotifiedRef`로 실행을 1회로 못박는다 — App Router는 기본 Strict Mode(next.config.ts에
 * 별도 설정이 없으면 true, Next.js 13.5.1부터 기본값)라 개발 모드에서 effect가 mount→cleanup→
 * remount로 2회 호출된다. 이 effect엔 cleanup이 없어 가드가 없으면 토스트가 두 번 뜬다 —
 * router.replace가 아직 반영되기 전(같은 커밋 내)에 두 번째 호출이 일어나 showError prop이
 * 그대로 true이기 때문이다. 프로덕션은 원래 1회지만, 사용자에게 실제로 보이는 부수효과(알림)는
 * Strict Mode 유무와 무관하게 항상 1회여야 한다.
 */
export function LogoutNotice({ showError }: LogoutNoticeProps) {
  const router = useRouter();
  const { showToast } = useFeedback();
  const hasNotifiedRef = useRef(false);

  useEffect(() => {
    if (!showError || hasNotifiedRef.current) {
      return;
    }
    hasNotifiedRef.current = true;

    // 내부 정보(백엔드 message 원문 등)는 노출하지 않는다 — 항상 이 고정 문구만 보여준다.
    showToast({ variant: 'warning', message: LOGOUT_ERROR_MESSAGE });
    router.replace('/login');
  }, [showError, showToast, router]);

  return null;
}
