import { useState, useEffect, useCallback, useRef } from 'react';
import ppmService from '../services/ppmService';
import type { AssetMaintenance, PPMFilters, CreatePPMData } from '../services/ppmService';

/**
 * Hook to fetch list of asset maintenances (PPM schedules) with filters and pagination
 */
export function usePPMs(
  filters?: PPMFilters,
  limit: number = 20,
  offset: number = 0,
  orderBy?: string
) {
  const [ppms, setPPMs] = useState<AssetMaintenance[]>([]);
  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 fetchPPMs = async () => {
      try {
        setLoading(true);
        
        const response = await ppmService.getAssetMaintenances(filters, undefined, limit, offset, orderBy);
        
        if (!isCancelled) {
          setPPMs(response.asset_maintenances);
          setTotalCount(response.total_count);
          setHasMore(response.has_more);
          setError(null);
        }
      } catch (err) {
        if (!isCancelled) {
          const errorMessage = err instanceof Error ? err.message : 'Failed to fetch PPM schedules';
          
          if (errorMessage.includes('417') || errorMessage.includes('Expectation Failed') || errorMessage.includes('has no attribute')) {
            setError('API endpoint not deployed. Please deploy ppm_api.py to your Frappe server.');
          } else {
            setError(errorMessage);
          }
          
          setPPMs([]);
          setTotalCount(0);
          setHasMore(false);
        }
      } finally {
        if (!isCancelled) {
          setLoading(false);
        }
      }
    };
    
    fetchPPMs();
    
    return () => {
      isCancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filtersJson, limit, offset, orderBy, refetchTrigger]);

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

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

/**
 * Hook to fetch a single PPM schedule by name
 */
export function usePPMDetails(ppmName: string | null) {
  const [ppm, setPPM] = useState<AssetMaintenance | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchPPM = useCallback(async () => {
    if (!ppmName) {
      setPPM(null);
      setLoading(false);
      return;
    }

    try {
      setLoading(true);
      setError(null);
      
      const data = await ppmService.getAssetMaintenanceDetails(ppmName);
      setPPM(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to fetch PPM details');
    } finally {
      setLoading(false);
    }
  }, [ppmName]);

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

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

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

/**
 * Hook to manage PPM operations (create, update, delete)
 */
export function usePPMMutations() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const createPPM = useCallback(async (data: CreatePPMData) => {
    try {
      setLoading(true);
      setError(null);
      const result = await ppmService.createAssetMaintenance(data);
      return result;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to create PPM schedule';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  }, []);

  const updatePPM = useCallback(async (ppmName: string, data: Partial<CreatePPMData>) => {
    try {
      setLoading(true);
      setError(null);
      const result = await ppmService.updateAssetMaintenance(ppmName, data);
      return result;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to update PPM schedule';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  }, []);

  const deletePPM = useCallback(async (ppmName: string) => {
    try {
      setLoading(true);
      setError(null);
      const result = await ppmService.deleteAssetMaintenance(ppmName);
      return result;
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to delete PPM schedule';
      setError(errorMessage);
      throw err;
    } finally {
      setLoading(false);
    }
  }, []);

  return { createPPM, updatePPM, deletePPM, loading, error };
}

