import { useState, useEffect, useCallback, useRef } from 'react';
import { netcattyBridge } from '../../../infrastructure/services/netcattyBridge';

export interface DiskInfo {
  mountPoint: string;
  used: number;               // Used in GB
  total: number;              // Total in GB
  percent: number;            // Usage percentage
}

export interface NetInterfaceInfo {
  name: string;               // Interface name (e.g., eth0, ens33)
  rxBytes: number;            // Total received bytes
  txBytes: number;            // Total transmitted bytes
  rxSpeed: number;            // Receive speed (bytes/sec)
  txSpeed: number;            // Transmit speed (bytes/sec)
}

export interface ProcessInfo {
  pid: string;
  memPercent: number;
  command: string;
}

export interface ServerStats {
  cpu: number | null;           // CPU usage percentage (0-100)
  cpuCores: number | null;      // Number of CPU cores
  cpuPerCore: number[];         // Per-core CPU usage array
  memTotal: number | null;      // Total memory in MB
  memUsed: number | null;       // Used memory in MB (excluding buffers/cache)
  memFree: number | null;       // Free memory in MB
  memBuffers: number | null;    // Buffers in MB
  memCached: number | null;     // Cached in MB
  swapTotal: number | null;     // Total swap in MB
  swapUsed: number | null;      // Used swap in MB
  topProcesses: ProcessInfo[];  // Top 10 processes by memory
  diskPercent: number | null;   // Disk usage percentage for root partition
  diskUsed: number | null;      // Disk used in GB
  diskTotal: number | null;     // Total disk in GB
  disks: DiskInfo[];            // All mounted disks
  netRxSpeed: number;           // Total network receive speed (bytes/sec)
  netTxSpeed: number;           // Total network transmit speed (bytes/sec)
  netInterfaces: NetInterfaceInfo[];  // Per-interface network stats
  lastUpdated: number | null;   // Timestamp of last successful update
}

interface UseServerStatsOptions {
  sessionId: string;
  enabled: boolean;           // Whether stats collection is enabled (from settings)
  refreshInterval: number;    // Refresh interval in seconds
  isLinux: boolean;           // Only collect stats for Linux servers
  isConnected: boolean;       // Only collect when connected
}

export function useServerStats({
  sessionId,
  enabled,
  refreshInterval,
  isLinux,
  isConnected,
}: UseServerStatsOptions) {
  const [stats, setStats] = useState<ServerStats>({
    cpu: null,
    cpuCores: null,
    cpuPerCore: [],
    memTotal: null,
    memUsed: null,
    memFree: null,
    memBuffers: null,
    memCached: null,
    swapTotal: null,
    swapUsed: null,
    topProcesses: [],
    diskPercent: null,
    diskUsed: null,
    diskTotal: null,
    disks: [],
    netRxSpeed: 0,
    netTxSpeed: 0,
    netInterfaces: [],
    lastUpdated: null,
  });
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const isMountedRef = useRef(true);

  const fetchStats = useCallback(async () => {
    if (!enabled || !isLinux || !isConnected || !sessionId) {
      return;
    }

    const bridge = netcattyBridge.get();
    if (!bridge?.getServerStats) {
      return;
    }

    setIsLoading(true);
    setError(null);

    try {
      const result = await bridge.getServerStats(sessionId);

      if (!isMountedRef.current) return;

      if (result.success && result.stats) {
        setStats({
          cpu: result.stats.cpu,
          cpuCores: result.stats.cpuCores,
          cpuPerCore: result.stats.cpuPerCore || [],
          memTotal: result.stats.memTotal,
          memUsed: result.stats.memUsed,
          memFree: result.stats.memFree,
          memBuffers: result.stats.memBuffers,
          memCached: result.stats.memCached,
          swapTotal: result.stats.swapTotal ?? null,
          swapUsed: result.stats.swapUsed ?? null,
          topProcesses: result.stats.topProcesses || [],
          diskPercent: result.stats.diskPercent,
          diskUsed: result.stats.diskUsed,
          diskTotal: result.stats.diskTotal,
          disks: result.stats.disks || [],
          netRxSpeed: result.stats.netRxSpeed || 0,
          netTxSpeed: result.stats.netTxSpeed || 0,
          netInterfaces: result.stats.netInterfaces || [],
          lastUpdated: Date.now(),
        });
      } else if (result.error) {
        setError(result.error);
      }
    } catch (err) {
      if (isMountedRef.current) {
        setError(err instanceof Error ? err.message : 'Unknown error');
      }
    } finally {
      if (isMountedRef.current) {
        setIsLoading(false);
      }
    }
  }, [sessionId, enabled, isLinux, isConnected]);

  // Initial fetch and periodic refresh
  useEffect(() => {
    isMountedRef.current = true;

    // Clear any existing interval
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }

    // Don't run if not enabled or not a Linux system
    if (!enabled || !isLinux || !isConnected) {
      // Reset stats when disabled or not connected
      setStats({
        cpu: null,
        cpuCores: null,
        cpuPerCore: [],
        memTotal: null,
        memUsed: null,
        memFree: null,
        memBuffers: null,
        memCached: null,
        swapTotal: null,
        swapUsed: null,
        topProcesses: [],
        diskPercent: null,
        diskUsed: null,
        diskTotal: null,
        disks: [],
        netRxSpeed: 0,
        netTxSpeed: 0,
        netInterfaces: [],
        lastUpdated: null,
      });
      return;
    }

    // Initial fetch with a small delay to let the connection stabilize
    const initialTimer = setTimeout(() => {
      fetchStats();
    }, 2000);

    // Set up periodic refresh
    const intervalMs = Math.max(5, refreshInterval) * 1000; // Minimum 5 seconds
    intervalRef.current = setInterval(fetchStats, intervalMs);

    return () => {
      isMountedRef.current = false;
      clearTimeout(initialTimer);
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };
  }, [enabled, isLinux, isConnected, refreshInterval, fetchStats]);

  // Manual refresh function
  const refresh = useCallback(() => {
    fetchStats();
  }, [fetchStats]);

  return {
    stats,
    isLoading,
    error,
    refresh,
  };
}
