import { useState, useEffect, useRef, useCallback } from 'react';
import { logger } from '../utils/logger';

export interface SystemMetrics {
  memoryUsage: number;
  cpuUsage: number;
  networkLatency: number;
  apiResponseTime: number;
  websocketStatus: 'connected' | 'disconnected' | 'connecting';
  dataQuality: {
    totalRecords: number;
    validRecords: number;
    invalidRecords: number;
    qualityScore: number;
  };
  sensorStatus: {
    totalSensors: number;
    activeSensors: number;
    inactiveSensors: number;
    lastUpdate: string;
  };
}

export interface PerformanceMetrics {
  componentRenderTime: number;
  apiCallTime: number;
  dataProcessingTime: number;
}

export const useMonitoring = () => {
  const [metrics, setMetrics] = useState<SystemMetrics>({
    memoryUsage: 0,
    cpuUsage: 0,
    networkLatency: 0,
    apiResponseTime: 0,
    websocketStatus: 'disconnected',
    dataQuality: {
      totalRecords: 0,
      validRecords: 0,
      invalidRecords: 0,
      qualityScore: 0
    },
    sensorStatus: {
      totalSensors: 0,
      activeSensors: 0,
      inactiveSensors: 0,
      lastUpdate: new Date().toISOString()
    }
  });

  const [performanceMetrics, setPerformanceMetrics] = useState<PerformanceMetrics>({
    componentRenderTime: 0,
    apiCallTime: 0,
    dataProcessingTime: 0
  });

  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const apiCallTimes = useRef<number[]>([]);
  const renderTimes = useRef<number[]>([]);

  // 메모리 사용량 측정
  const measureMemoryUsage = useCallback(() => {
    if ('memory' in performance) {
      const memory = (performance as any).memory;
      const usage = (memory.usedJSHeapSize / memory.totalJSHeapSize) * 100;
      return Math.round(usage * 100) / 100;
    }
    return 0;
  }, []);

  // 네트워크 지연 시간 측정
  const measureNetworkLatency = useCallback(async () => {
    const start = performance.now();
    try {
      await fetch('/api/health', { method: 'GET' });
      const end = performance.now();
      return end - start;
    } catch (error) {
      logger.warn('Network latency measurement failed', { error });
      return 0;
    }
  }, []);

  // 데이터 품질 평가
  const evaluateDataQuality = useCallback((data: any[]) => {
    if (data.length === 0) {
      return {
        totalRecords: 0,
        validRecords: 0,
        invalidRecords: 0,
        qualityScore: 0
      };
    }

    const validRecords = data.filter(item => {
      return item && 
             typeof item.temperature === 'number' && 
             typeof item.humidity === 'number' &&
             !isNaN(item.temperature) && 
             !isNaN(item.humidity);
    }).length;

    const invalidRecords = data.length - validRecords;
    const qualityScore = (validRecords / data.length) * 100;

    return {
      totalRecords: data.length,
      validRecords,
      invalidRecords,
      qualityScore: Math.round(qualityScore * 100) / 100
    };
  }, []);

  // 센서 상태 업데이트
  const updateSensorStatus = useCallback((devices: any[]) => {
    const activeSensors = devices.filter(d => d.status === 'active').length;
    const totalSensors = devices.length;
    const inactiveSensors = totalSensors - activeSensors;

    return {
      totalSensors,
      activeSensors,
      inactiveSensors,
      lastUpdate: new Date().toISOString()
    };
  }, []);

  // 성능 메트릭 업데이트
  const updatePerformanceMetrics = useCallback(() => {
    if (apiCallTimes.current.length > 0) {
      const avgApiCallTime = apiCallTimes.current.reduce((a, b) => a + b, 0) / apiCallTimes.current.length;
      setPerformanceMetrics(prev => ({
        ...prev,
        apiCallTime: Math.round(avgApiCallTime * 100) / 100
      }));
    }

    if (renderTimes.current.length > 0) {
      const avgRenderTime = renderTimes.current.reduce((a, b) => a + b, 0) / renderTimes.current.length;
      setPerformanceMetrics(prev => ({
        ...prev,
        componentRenderTime: Math.round(avgRenderTime * 100) / 100
      }));
    }
  }, []);

  // 메트릭 수집 시작
  const startMonitoring = useCallback(() => {
    if (intervalRef.current) return;

    intervalRef.current = setInterval(async () => {
      const memoryUsage = measureMemoryUsage();
      const networkLatency = await measureNetworkLatency();

      setMetrics(prev => ({
        ...prev,
        memoryUsage,
        networkLatency: Math.round(networkLatency * 100) / 100
      }));

      updatePerformanceMetrics();
    }, 5000); // 5초마다 수집

    logger.info('System monitoring started');
  }, [measureMemoryUsage, measureNetworkLatency, updatePerformanceMetrics]);

  // 메트릭 수집 중지
  const stopMonitoring = useCallback(() => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
      logger.info('System monitoring stopped');
    }
  }, []);

  // API 호출 시간 기록
  const recordApiCallTime = useCallback((duration: number) => {
    apiCallTimes.current.push(duration);
    if (apiCallTimes.current.length > 10) {
      apiCallTimes.current = apiCallTimes.current.slice(-10);
    }
  }, []);

  // 컴포넌트 렌더링 시간 기록
  const recordRenderTime = useCallback((duration: number) => {
    renderTimes.current.push(duration);
    if (renderTimes.current.length > 10) {
      renderTimes.current = renderTimes.current.slice(-10);
    }
  }, []);

  // 데이터 품질 업데이트
  const updateDataQuality = useCallback((data: any[]) => {
    const quality = evaluateDataQuality(data);
    setMetrics(prev => ({
      ...prev,
      dataQuality: quality
    }));

    if (quality.qualityScore < 80) {
      logger.warn('Data quality below threshold', { quality });
    }
  }, [evaluateDataQuality]);

  // 센서 상태 업데이트
  const updateSensorStatusData = useCallback((devices: any[]) => {
    const status = updateSensorStatus(devices);
    setMetrics(prev => ({
      ...prev,
      sensorStatus: status
    }));
  }, [updateSensorStatus]);

  // WebSocket 상태 업데이트
  const updateWebSocketStatus = useCallback((status: 'connected' | 'disconnected' | 'connecting') => {
    setMetrics(prev => ({
      ...prev,
      websocketStatus: status
    }));
  }, []);

  useEffect(() => {
    startMonitoring();
    return () => stopMonitoring();
  }, [startMonitoring, stopMonitoring]);

  return {
    metrics,
    performanceMetrics,
    recordApiCallTime,
    recordRenderTime,
    updateDataQuality,
    updateSensorStatus: updateSensorStatusData,
    updateWebSocketStatus,
    startMonitoring,
    stopMonitoring
  };
}; 