import { useState, useEffect, useCallback, useRef } from 'react';
import assetMaintenanceService from '../services/assetMaintenanceService';
import type { AssetMaintenanceLog, MaintenanceFilters, CreateMaintenanceData } from '../services/assetMaintenanceService';

/**
 * Hook to fetch list of asset maintenance logs with filters and pagination
 */
export function useAssetMaintenanceLogs(
  filters?: MaintenanceFilters,
  limit: number = 20,
  offset: number = 0,
  orderBy?: string
) {
  const [logs, setLogs] = useState<AssetMaintenanceLog[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [hasMore, setHasMore] = useState(false);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [refetchTrigger, setRefetchTrigger] = useState(0);
  const hasAttemptedRef = useRef(false);

  const filtersJson = JSON.stringify(filters);

  useEffect(() => {
    if (hasAttemptedRef.current && error) {
      return;
    }

    let isCancelled = false;
    hasAttemptedRef.current = true;
    
    const fetchLogs = async () => {
      try {
        setLoading(true);
        
        const response = await assetMaintenanceService.getMaintenanceLogs(filters, undefined, limit, offset, orderBy);
        
        if (!isCancelled) {
          setLogs(response.asset_maintenance_logs);
          setTotalCount(response.total_count);
          setHasMore(response.has_more);
          setError(null);
        }
      } catch (err) {
        if (!isCancelled) {
          const errorMessage = err instanceof Error ? err.message : 'Failed to fetch maintenance logs';
          
          if (errorMessage.includes('417') || errorMessage.includes('Expectation Failed') || errorMessage.includes('has no attribute')) {
            setError('API endpoint not deployed. Please deploy asset_maintenance_api.py to your Frappe server.');
          } else {
            setError(errorMessage);
          }
          
          setLogs([]);
          setTotalCount(0);
          setHasMore(false);
        }
      } finally {
        if (!isCancelled) {
          setLoading(false);
        }
      }
    };
    
    fetchLogs();
    
    return () => {
      isCancelled = true;
    };
  }, [filtersJson, limit, offset, orderBy, refetchTrigger]);

  const refetch = useCallback(() => {
    hasAttemptedRef.current = false;
    setRefetchTrigger(prev => prev + 1);
  }, []);

  return { logs, totalCount, hasMore, loading, error, refetch };
}

/**
 * Hook to fetch a single maintenance log by name
 */
export function useMaintenanceLogDetails(logName: string | null) {
  const [log, setLog] = useState<AssetMaintenanceLog | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchLog = useCallback(async () => {
    if (!logName) {
      setLog(null);
      setLoading(false);
      return;
    }

    try {
      setLoading(true);
      setError(null);
      
      const data = await assetMaintenanceService.getMaintenanceLogDetails(logName);
      setLog(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to fetch maintenance log details');
    } finally {
      setLoading(false);
    }
  }, [logName]);

  useEffect(() => {
    fetchLog();
  }, [fetchLog]);

  const refetch = useCallback(() => {
    fetchLog();
  }, [fetchLog]);

  return { log, loading, error, refetch };
}

/**
 * Hook to manage maintenance log operations
 */
export function useMaintenanceMutations() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const createLog = async (logData: CreateMaintenanceData) => {
    try {
      setLoading(true);
      setError(null);
      
      console.log('[useMaintenanceMutations] Creating maintenance log:', logData);
      const response = await assetMaintenanceService.createMaintenanceLog(logData);
      console.log('[useMaintenanceMutations] Create response:', response);
      
      if (response.success) {
        return response.asset_maintenance_log;
      } else {
        const backendError = (response as any).error || 'Failed to create maintenance log';
        throw new Error(backendError);
      }
    } catch (err) {
      console.error('[useMaintenanceMutations] Create error:', err);
      const errorMessage = err instanceof Error ? err.message : 'Failed to create maintenance log';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  };

  const updateLog = async (logName: string, logData: Partial<CreateMaintenanceData>) => {
    try {
      setLoading(true);
      setError(null);
      
      console.log('[useMaintenanceMutations] Updating maintenance log:', logName, logData);
      const response = await assetMaintenanceService.updateMaintenanceLog(logName, logData);
      console.log('[useMaintenanceMutations] Update response:', response);
      
      if (response.success) {
        return response.asset_maintenance_log;
      } else {
        const backendError = (response as any).error || 'Failed to update maintenance log';
        throw new Error(backendError);
      }
    } catch (err) {
      console.error('[useMaintenanceMutations] Update error:', err);
      const errorMessage = err instanceof Error ? err.message : 'Failed to update maintenance log';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  };

  const deleteLog = async (logName: string) => {
    try {
      setLoading(true);
      setError(null);
      
      const response = await assetMaintenanceService.deleteMaintenanceLog(logName);
      
      if (!response.success) {
        throw new Error('Failed to delete maintenance log');
      }
      
      return response;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to delete maintenance log';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  };

  const updateStatus = async (logName: string, maintenanceStatus?: string, workflowState?: string) => {
    try {
      setLoading(true);
      setError(null);
      
      const response = await assetMaintenanceService.updateMaintenanceStatus(logName, maintenanceStatus, workflowState);
      
      if (response.success) {
        return response.asset_maintenance_log;
      } else {
        throw new Error('Failed to update maintenance status');
      }
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to update status';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  };

  return { createLog, updateLog, deleteLog, updateStatus, loading, error };
}

/**
 * Hook to fetch maintenance logs for a specific asset
 */
export function useAssetMaintenanceHistory(assetName: string | null) {
  const [logs, setLogs] = useState<AssetMaintenanceLog[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchHistory = useCallback(async () => {
    if (!assetName) {
      setLogs([]);
      setLoading(false);
      return;
    }

    try {
      setLoading(true);
      setError(null);
      
      const response = await assetMaintenanceService.getMaintenanceLogsByAsset(assetName);
      setLogs(response.asset_maintenance_logs);
      setTotalCount(response.total_count);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to fetch maintenance history');
    } finally {
      setLoading(false);
    }
  }, [assetName]);

  useEffect(() => {
    fetchHistory();
  }, [fetchHistory]);

  return { logs, totalCount, loading, error, refetch: fetchHistory };
}

/**
 * Hook to fetch overdue maintenance logs
 */
export function useOverdueMaintenanceLogs() {
  const [logs, setLogs] = useState<AssetMaintenanceLog[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchOverdue = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      
      const response = await assetMaintenanceService.getOverdueMaintenanceLogs();
      setLogs(response.asset_maintenance_logs);
      setTotalCount(response.total_count);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to fetch overdue maintenance');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchOverdue();
  }, [fetchOverdue]);

  return { logs, totalCount, loading, error, refetch: fetchOverdue };
}

