import { useCallback, useState } from 'react';

const initialState = {
  active: false,
  percent: 0,
  message: '',
  block: false,
  etaSeconds: null
};

const useSyncProgress = () => {
  const [syncProgress, setSyncProgress] = useState(initialState);

  const startSyncProgress = useCallback((message, percent = 0, block = false) => {
    setSyncProgress({ active: true, percent, message, block, etaSeconds: null });
  }, []);

  const updateSyncProgress = useCallback((message, percent, extra = {}) => {
    setSyncProgress((prev) => {
      if (!prev.active) {
        return prev;
      }
      let nextPercent = prev.percent ?? 0;
      if (typeof percent === 'number' && Number.isFinite(percent)) {
        const bounded = Math.min(100, Math.max(percent, 0));
        nextPercent = Math.max(bounded, nextPercent);
      }
      return {
        ...prev,
        message: message ?? prev.message,
        percent: nextPercent,
        etaSeconds:
          Object.prototype.hasOwnProperty.call(extra, 'etaSeconds') && extra.etaSeconds !== undefined
            ? extra.etaSeconds
            : prev.etaSeconds ?? null
      };
    });
  }, []);

  const finishSyncProgress = useCallback(() => {
    setSyncProgress((prev) => {
      if (!prev.active) {
        return prev;
      }
      return { ...prev, percent: 100, etaSeconds: null };
    });
    setTimeout(() => {
      setSyncProgress(initialState);
    }, 400);
  }, []);

  const nudgeSyncProgress = useCallback((message, increment = 2, ceiling = 80) => {
    setSyncProgress((prev) => {
      if (!prev.active) {
        return prev;
      }
      const nextPercent = Math.min(ceiling, (prev.percent || 0) + increment);
      return {
        ...prev,
        percent: nextPercent,
        message: message || prev.message
      };
    });
  }, []);

  return {
    syncProgress,
    startSyncProgress,
    updateSyncProgress,
    finishSyncProgress,
    nudgeSyncProgress
  };
};

export default useSyncProgress;
