import { useState, useEffect, useCallback } from 'react';
import apiService from '../services/apiService';

// Types for PM Schedule Generator
export interface PMEntryLine {
  name?: string;
  asset: string;
  asset_name: string;
  start_date: string;
  end_date: string;
  manufacturer?: string;
  model?: string;
  idx?: number;
}

export interface PMSchedule {
  name: string;
  owner?: string;
  creation?: string;
  modified?: string;
  modified_by?: string;
  docstatus?: number;
  hospital?: string;
  modality?: string;
  device_status?: string;
  start_date?: string;
  end_date?: string;
  maintenance_team?: string;
  maintenance_manager?: string;
  periodicity?: string;
  assign_to?: string;
  due_date?: string;
  pm_for?: string; // PM Name field
  maintenance_entries?: PMEntryLine[];
  doctype?: string;
  [key: string]: any; // Allow additional fields
}

export interface CreatePMScheduleData {
  hospital: string;
  modality?: string;
  device_status?: string;
  start_date: string;
  end_date: string;
  maintenance_team?: string;
  maintenance_manager?: string;
  periodicity: string;
  assign_to?: string;
  due_date?: string;
  maintenance_entries?: PMEntryLine[];
}

// Hook for fetching PM Schedules list
export function usePMSchedules(
  filters: Record<string, any> = {},
  limit: number = 20,
  offset: number = 0,
  orderBy: string = 'creation desc',
  permissionFilters: Record<string, any> = {}
) {
  const [pmSchedules, setPMSchedules] = useState<PMSchedule[]>([]);
  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);

  // Stringify filters to prevent object reference changes from causing re-renders
  const filtersJson = JSON.stringify(filters);
  const permissionFiltersJson = JSON.stringify(permissionFilters);

  useEffect(() => {
    let isCancelled = false;

    // Capture values at effect execution time
    const currentFiltersJson = filtersJson;
    const currentPermissionFiltersJson = permissionFiltersJson;
    const currentLimit = limit;
    const currentOffset = offset;
    const currentOrderBy = orderBy;

    const fetchPMSchedules = async () => {
      try {
        setLoading(true);
        setError(null);

        // Parse filters from JSON strings to avoid closure issues
        let currentFilters: Record<string, any> = {};
        let currentPermissionFilters: Record<string, any> = {};
        
        try {
          currentFilters = currentFiltersJson ? JSON.parse(currentFiltersJson) : {};
        } catch (e) {
          currentFilters = {};
        }
        
        try {
          currentPermissionFilters = currentPermissionFiltersJson ? JSON.parse(currentPermissionFiltersJson) : {};
        } catch (e) {
          currentPermissionFilters = {};
        }
        
        // Merge filters with permission filters
        const combinedFilters = { ...currentFilters, ...currentPermissionFilters };
        
        const response = await apiService.apiCall<any>(
          '/api/method/asset_lite.api.ppm_generator_api.get_pm_schedules',
          {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              filters: JSON.stringify(combinedFilters),
              limit: currentLimit,
              offset: currentOffset,
              order_by: currentOrderBy,
              include_child_tables: true,
              fields: JSON.stringify(['name', 'pm_for', 'hospital', 'modality', 'periodicity', 'start_date', 'end_date', 'due_date']) // Explicitly request pm_for
            })
          }
        );

        if (!isCancelled) {
          // Handle both response formats: {message: {...}} or direct {...}
          const data = response?.message || response;
          
          if (data && data.pm_schedules) {
            const schedules = data.pm_schedules || [];
            console.log('[usePMSchedules] Loaded', schedules.length, 'PM Schedules');
            
            // Debug: Log first schedule to see available fields - ALWAYS log in dev
            if (schedules.length > 0) {
              const firstSchedule = schedules[0];
              console.log('[usePMSchedules] 🔍 FIRST SCHEDULE FIELDS:', {
                name: firstSchedule.name,
                pm_for: firstSchedule.pm_for,
                'pm_for (bracket)': firstSchedule['pm_for'],
                allKeys: Object.keys(firstSchedule),
                allKeysList: Object.keys(firstSchedule).join(', '),
                fullObject: firstSchedule
              });
            }
            
            setPMSchedules(schedules);
            setTotalCount(data.total_count || 0);
            setHasMore(data.has_more || false);
          } else {
            console.warn('[usePMSchedules] No pm_schedules in response:', response);
            setPMSchedules([]);
            setTotalCount(0);
            setHasMore(false);
          }
        }
      } catch (err) {
        if (!isCancelled) {
          console.error('Error fetching PM Schedules:', err);
          setError(err instanceof Error ? err.message : 'Failed to fetch PM Schedules');
          setPMSchedules([]);
          setTotalCount(0);
        }
      } finally {
        if (!isCancelled) {
          setLoading(false);
        }
      }
    };

    fetchPMSchedules();

    return () => {
      isCancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filtersJson, permissionFiltersJson, limit, offset, orderBy, refetchTrigger]);

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

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

// Hook for fetching single PM Schedule details
export function usePMScheduleDetails(pmScheduleName: string | null) {
  const [pmSchedule, setPMSchedule] = useState<PMSchedule | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const fetchPMSchedule = useCallback(async () => {
    if (!pmScheduleName) {
      setPMSchedule(null);
      setLoading(false);
      return;
    }

    setLoading(true);
    setError(null);

    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.get_pm_schedule_details',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ pm_schedule_name: pmScheduleName })
        }
      );

      console.log('[usePMScheduleDetails] API Response:', response);

      // apiService.apiCall already unwraps the 'message' property
      // So response is directly the PM Schedule data OR an error object
      if (response && response.name && !response.error) {
        console.log('[usePMScheduleDetails] Setting PM Schedule:', response);
        setPMSchedule(response);
      } else {
        const errorMsg = response?.error || 'PM Schedule not found';
        console.warn('[usePMScheduleDetails] Error or not found:', errorMsg);
        setError(errorMsg);
        setPMSchedule(null);
      }
    } catch (err) {
      console.error('Error fetching PM Schedule details:', err);
      setError(err instanceof Error ? err.message : 'Failed to fetch PM Schedule');
      setPMSchedule(null);
    } finally {
      setLoading(false);
    }
  }, [pmScheduleName]);

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

  return {
    pmSchedule,
    loading,
    error,
    refetch: fetchPMSchedule
  };
}

// Hook for PM Schedule mutations (create, update, delete, submit, cancel)
export function usePMScheduleMutations() {
  const [loading, setLoading] = useState(false);

  const createPMSchedule = async (data: CreatePMScheduleData): Promise<PMSchedule> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.create_pm_schedule',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ pm_schedule_data: JSON.stringify(data) })
        }
      );

      // apiService.apiCall already unwraps the 'message' property
      if (response?.success) {
        return response.pm_schedule;
      } else {
        throw new Error(response?.error || 'Failed to create PM Schedule');
      }
    } finally {
      setLoading(false);
    }
  };

  const updatePMSchedule = async (name: string, data: Partial<CreatePMScheduleData>): Promise<PMSchedule> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.update_pm_schedule',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            pm_schedule_name: name,
            pm_schedule_data: JSON.stringify(data)
          })
        }
      );

      if (response?.success) {
        return response.pm_schedule;
      } else {
        throw new Error(response?.error || 'Failed to update PM Schedule');
      }
    } finally {
      setLoading(false);
    }
  };

  const deletePMSchedule = async (name: string): Promise<void> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.delete_pm_schedule',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ pm_schedule_name: name })
        }
      );

      if (!response?.success) {
        throw new Error(response?.error || 'Failed to delete PM Schedule');
      }
    } finally {
      setLoading(false);
    }
  };

  const submitPMSchedule = async (name: string): Promise<PMSchedule> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.submit_pm_schedule',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ pm_schedule_name: name })
        }
      );

      if (response?.success) {
        return response.pm_schedule;
      } else {
        throw new Error(response?.error || 'Failed to submit PM Schedule');
      }
    } finally {
      setLoading(false);
    }
  };

  const cancelPMSchedule = async (name: string): Promise<PMSchedule> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.cancel_pm_schedule',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ pm_schedule_name: name })
        }
      );

      if (response?.success) {
        return response.pm_schedule;
      } else {
        throw new Error(response?.error || 'Failed to cancel PM Schedule');
      }
    } finally {
      setLoading(false);
    }
  };

  const addMaintenanceEntry = async (pmScheduleName: string, entryData: Partial<PMEntryLine>): Promise<PMEntryLine[]> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.add_maintenance_entry',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            pm_schedule_name: pmScheduleName,
            entry_data: JSON.stringify(entryData)
          })
        }
      );

      if (response?.success) {
        return response.maintenance_entries;
      } else {
        throw new Error(response?.error || 'Failed to add maintenance entry');
      }
    } finally {
      setLoading(false);
    }
  };

  const removeMaintenanceEntry = async (pmScheduleName: string, entryName: string): Promise<PMEntryLine[]> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.remove_maintenance_entry',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            pm_schedule_name: pmScheduleName,
            entry_name: entryName
          })
        }
      );

      if (response?.success) {
        return response.maintenance_entries;
      } else {
        throw new Error(response?.error || 'Failed to remove maintenance entry');
      }
    } finally {
      setLoading(false);
    }
  };

  const updateMaintenanceEntry = async (
    pmScheduleName: string,
    entryName: string,
    entryData: Partial<PMEntryLine>
  ): Promise<PMEntryLine[]> => {
    setLoading(true);
    try {
      const response = await apiService.apiCall<any>(
        '/api/method/asset_lite.api.ppm_generator_api.update_maintenance_entry',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            pm_schedule_name: pmScheduleName,
            entry_name: entryName,
            entry_data: JSON.stringify(entryData)
          })
        }
      );

      if (response?.success) {
        return response.maintenance_entries;
      } else {
        throw new Error(response?.error || 'Failed to update maintenance entry');
      }
    } finally {
      setLoading(false);
    }
  };

  return {
    createPMSchedule,
    updatePMSchedule,
    deletePMSchedule,
    submitPMSchedule,
    cancelPMSchedule,
    addMaintenanceEntry,
    removeMaintenanceEntry,
    updateMaintenanceEntry,
    loading
  };
}

export default {
  usePMSchedules,
  usePMScheduleDetails,
  usePMScheduleMutations
};