import { useCallback, useEffect, useRef, useState } from 'react'

interface UseDelayedSaveOptions<T> {
  onSave: (data: T) => Promise<void>
  onSuccess?: (data: T) => void // Коллбек после успешного сохранения
  delay?: number // Задержка в миллисекундах (по умолчанию 2000мс)
}

interface UseDelayedSaveReturn<T> {
  hasUnsavedChanges: boolean
  isSaving: boolean
  lastSaveError: string | null
  updateData: (data: T) => void
  manualSave: () => Promise<void>
  clearError: () => void
}

export function useDelayedSave<T>({
  onSave,
  onSuccess,
  delay = 2000,
}: UseDelayedSaveOptions<T>): UseDelayedSaveReturn<T> {
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
  const [isSaving, setIsSaving] = useState(false)
  const [lastSaveError, setLastSaveError] = useState<string | null>(null)

  const timeoutRef = useRef<NodeJS.Timeout | null>(null)
  const pendingDataRef = useRef<T | null>(null)

  // Очистка таймера при размонтировании компонента
  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current)
      }
    }
  }, [])

  const clearError = useCallback(() => {
    setLastSaveError(null)
  }, [])

  const performSave = useCallback(
    async (data: T) => {
      if (isSaving) return

      setIsSaving(true)
      setLastSaveError(null)

      try {
        await onSave(data)
        setHasUnsavedChanges(false)
        pendingDataRef.current = null
        // Вызываем коллбек успешного сохранения
        onSuccess?.(data)
      } catch (error) {
        const errorMessage =
          error instanceof Error ? error.message : 'Неизвестная ошибка'
        setLastSaveError(errorMessage)
        console.error('Ошибка при сохранении:', error)
      } finally {
        setIsSaving(false)
      }
    },
    [onSave, onSuccess, isSaving]
  )

  const updateData = useCallback(
    (data: T) => {
      // Отменяем предыдущий таймер
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current)
      }

      // Сохраняем данные для отложенного сохранения
      pendingDataRef.current = data
      setHasUnsavedChanges(true)
      setLastSaveError(null)

      // Устанавливаем новый таймер
      timeoutRef.current = setTimeout(() => {
        if (pendingDataRef.current) {
          performSave(pendingDataRef.current)
        }
      }, delay)
    },
    [delay, performSave]
  )

  const manualSave = useCallback(async () => {
    // Отменяем автоматическое сохранение
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current)
      timeoutRef.current = null
    }

    // Сохраняем немедленно, если есть несохранённые данные
    if (pendingDataRef.current) {
      await performSave(pendingDataRef.current)
    }
  }, [performSave])

  return {
    hasUnsavedChanges,
    isSaving,
    lastSaveError,
    updateData,
    manualSave,
    clearError,
  }
}
