/**
 * SSE(Server-Sent Events) 기반 실시간 알림 훅
 * - EventSource로 서버 연결
 * - 네트워크 순단 시 자동 재연결
 * - 컴포넌트 언마운트 시 Cleanup
 */
import { useEffect, useRef, useCallback, useState } from 'react';
import { getNotificationApiBaseUrl } from '../services/apiConfig';

export interface NotificationPayload {
  id: number;
  userId: number | null;
  symbol: string;
  message: string;
  koreanName: string;
  timestamp: number;
}

export type NotificationHandler = (payload: NotificationPayload) => void;

interface UseNotificationOptions {
  /** 토큰 (선택, 로그인 시) */
  token?: string | null;
  /** 알림 수신 시 콜백 */
  onNotification?: NotificationHandler;
  /** 연결 상태 변경 시 콜백 */
  onStatusChange?: (status: 'connecting' | 'connected' | 'disconnected' | 'error') => void;
  /** 활성화 여부 (false면 연결하지 않음) */
  enabled?: boolean;
  /** 재연결 대기 시간 (ms) */
  reconnectDelay?: number;
  /** 최대 재연결 시도 횟수 (0 = 무제한) */
  maxReconnectAttempts?: number;
}

export function useNotification({
  token,
  onNotification,
  onStatusChange,
  enabled = true,
  reconnectDelay = 3000,
  maxReconnectAttempts = 0,
}: UseNotificationOptions = {}) {
  const eventSourceRef = useRef<EventSource | null>(null);
  const reconnectAttemptsRef = useRef(0);
  const reconnectTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const onNotificationRef = useRef(onNotification);
  const onStatusChangeRef = useRef(onStatusChange);

  onNotificationRef.current = onNotification;
  onStatusChangeRef.current = onStatusChange;

  const connect = useCallback(() => {
    if (!enabled) return;

    const apiBase = getNotificationApiBaseUrl();
    const url = new URL(`${apiBase}/notifications/subscribe`);
    console.log('[useNotification] SSE 연결 시도:', url.toString());
    if (token) {
      url.searchParams.set('token', token);
    }

    const es = new EventSource(url.toString());
    eventSourceRef.current = es;

    onStatusChangeRef.current?.('connecting');

    es.addEventListener('connected', () => {
      reconnectAttemptsRef.current = 0;
      onStatusChangeRef.current?.('connected');
    });

    es.addEventListener('notification', (event: MessageEvent) => {
      try {
        console.log('[useNotification] 알림 수신:', event.data);
        const payload = JSON.parse(event.data) as NotificationPayload;
        onNotificationRef.current?.(payload);
      } catch (e) {
        console.error('[useNotification] Parse error:', e);
      }
    });

    es.addEventListener('heartbeat', () => {
      // 연결 유지 확인
    });

    es.onerror = () => {
      es.close();
      eventSourceRef.current = null;
      onStatusChangeRef.current?.('error');

      if (maxReconnectAttempts === 0 || reconnectAttemptsRef.current < maxReconnectAttempts) {
        reconnectAttemptsRef.current += 1;
        reconnectTimeoutRef.current = setTimeout(() => {
          connect();
        }, reconnectDelay);
      } else {
        onStatusChangeRef.current?.('disconnected');
      }
    };

    es.onopen = () => {
      console.log('[useNotification] SSE 연결됨');
      onStatusChangeRef.current?.('connected');
    };
  }, [enabled, token, reconnectDelay, maxReconnectAttempts]);

  const disconnect = useCallback(() => {
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
      reconnectTimeoutRef.current = null;
    }
    if (eventSourceRef.current) {
      eventSourceRef.current.close();
      eventSourceRef.current = null;
    }
    onStatusChangeRef.current?.('disconnected');
  }, []);

  useEffect(() => {
    if (enabled) {
      connect();
    }
    return () => {
      disconnect();
    };
  }, [enabled, connect, disconnect]);

  return { connect, disconnect };
}
