/**
 * 네트워크 모니터링 유틸리티
 */
import { NetworkEventHandlers, ExtendedWindow } from './types';
import { setNetworkStatus, getNetworkStatus } from './status';
import { checkNetworkStatus } from './checker';
import { processPendingSyncQueue } from './queue';

// 네트워크 모니터링 상태
let isMonitoring = false;
let networkCheckInterval: ReturnType<typeof setInterval> | null = null;

// 네트워크 재연결 시도 설정
const RECONNECT_INTERVAL = 5000; // 5초마다 재연결 시도
const MAX_RECONNECT_ATTEMPTS = 10; // 최대 재연결 시도 횟수
let reconnectAttempts = 0;
let reconnectTimer: ReturnType<typeof setTimeout> | null = null;

/**
 * 네트워크 재연결 시도
 */
export const attemptReconnect = async (): Promise<boolean> => {
  if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
    console.log(`[네트워크] 최대 재연결 시도 횟수(${MAX_RECONNECT_ATTEMPTS}회) 도달`);
    return false;
  }
  
  reconnectAttempts++;
  console.log(`[네트워크] 재연결 시도 ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS}`);
  
  // 재연결 상태로 변경
  setNetworkStatus('reconnecting');
  
  try {
    const isOnline = await checkNetworkStatus();
    
    if (isOnline) {
      console.log('[네트워크] 재연결 성공');
      setNetworkStatus('online');
      reconnectAttempts = 0;
      
      // 대기 중인 동기화 작업 처리
      processPendingSyncQueue().catch(err => {
        console.error('[네트워크] 재연결 후 동기화 큐 처리 중 오류:', err);
      });
      
      return true;
    } else {
      console.log('[네트워크] 재연결 실패, 재시도 예정');
      setNetworkStatus('offline');
      
      // 다음 재연결 시도 예약
      reconnectTimer = setTimeout(attemptReconnect, RECONNECT_INTERVAL);
      return false;
    }
  } catch (error) {
    console.error('[네트워크] 재연결 시도 중 오류:', error);
    setNetworkStatus('offline');
    
    // 다음 재연결 시도 예약
    reconnectTimer = setTimeout(attemptReconnect, RECONNECT_INTERVAL);
    return false;
  }
};

/**
 * 네트워크 상태 모니터링 시작
 */
export const startNetworkMonitoring = (): void => {
  if (isMonitoring) {
    return;
  }
  
  isMonitoring = true;
  
  // 초기 네트워크 상태를 온라인으로 설정 (실제 확인 전)
  setNetworkStatus('online');
  
  // 초기 네트워크 상태 확인
  checkNetworkStatus().then(isOnline => {
    if (!isOnline) {
      // 오프라인 상태면 재연결 시도 시작
      reconnectTimer = setTimeout(attemptReconnect, RECONNECT_INTERVAL);
    }
  });
  
  // 브라우저 온라인/오프라인 이벤트 리스너
  const handleOnline = () => {
    console.log('[네트워크] 브라우저 온라인 이벤트 감지');
    setNetworkStatus('online');
    reconnectAttempts = 0;
    
    // 대기 중인 동기화 작업 처리
    processPendingSyncQueue().catch(err => {
      console.error('[네트워크] 온라인 전환 후 동기화 큐 처리 중 오류:', err);
    });
  };
  
  const handleOffline = () => {
    console.log('[네트워크] 브라우저 오프라인 이벤트 감지');
    setNetworkStatus('offline');
    
    // 재연결 시도 시작
    reconnectTimer = setTimeout(attemptReconnect, RECONNECT_INTERVAL);
  };
  
  // 이벤트 리스너 등록 및 참조 저장
  window.addEventListener('online', handleOnline);
  window.addEventListener('offline', handleOffline);
  
  // 전역 변수에 이벤트 핸들러 참조 저장
  (window as ExtendedWindow).__networkHandlers = {
    handleOnline,
    handleOffline
  };
  
  // 정기적인 네트워크 상태 확인 (30초마다)
  networkCheckInterval = setInterval(async () => {
    try {
      const isOnline = await checkNetworkStatus();
      const currentStatus = getNetworkStatus();
      
      if (isOnline && currentStatus !== 'online') {
        // 오프라인에서 온라인으로 변경
        setNetworkStatus('online');
        reconnectAttempts = 0;
        
        // 대기 중인 동기화 작업 처리
        processPendingSyncQueue().catch(err => {
          console.error('[네트워크] 정기 확인 후 동기화 큐 처리 중 오류:', err);
        });
      } else if (!isOnline && currentStatus === 'online') {
        // 온라인에서 오프라인으로 변경
        setNetworkStatus('offline');
        
        // 재연결 시도 시작
        if (!reconnectTimer) {
          reconnectTimer = setTimeout(attemptReconnect, RECONNECT_INTERVAL);
        }
      }
    } catch (error) {
      console.error('[네트워크] 정기 네트워크 상태 확인 중 오류:', error);
    }
  }, 30000);
  
  console.log('[네트워크] 네트워크 모니터링 시작');
};

/**
 * 네트워크 상태 모니터링 중지
 */
export const stopNetworkMonitoring = (): void => {
  if (!isMonitoring) {
    return;
  }
  
  isMonitoring = false;
  
  // 브라우저 이벤트 리스너 제거
  const handlers = (window as ExtendedWindow).__networkHandlers;
  if (handlers) {
    window.removeEventListener('online', handlers.handleOnline);
    window.removeEventListener('offline', handlers.handleOffline);
    delete (window as ExtendedWindow).__networkHandlers;
  }
  
  // 인터벌 및 타이머 정리
  if (networkCheckInterval) {
    clearInterval(networkCheckInterval);
    networkCheckInterval = null;
  }
  
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
  
  reconnectAttempts = 0;
  
  console.log('[네트워크] 네트워크 모니터링 중지');
};
