import { useEffect, useState } from 'react';
import { useLockState } from './useWalletData';

// The unlock window, as a second-by-second countdown.
//
// The sidecar's `secondsRemaining` is a snapshot taken when the request was served, and re-polling once a
// second to animate a clock would be absurd. So the poll re-syncs the truth every ten seconds and this
// hook interpolates between syncs from React Query's `dataUpdatedAt`, which is the wall time the snapshot
// arrived. Drift is bounded by the poll interval and always errs towards showing LESS time than remains —
// a countdown that overstates the window is the one that surprises you mid-signature.
//
// When it reaches zero the UI flips to locked immediately rather than waiting for the next poll to agree.
// Nothing else is invalidated when that happens: every read in this app works fine against a locked
// wallet, and blowing the caches away would make an expiring timer look like a connection failure.

export type LockCountdown = {
  /** Null while the first lock-state request is in flight, or when no wallet is selected. */
  hasSeed: boolean | null;
  unlocked: boolean;
  secondsRemaining: number;
  isLoading: boolean;
};

export function useLockCountdown(walletId: number | null): LockCountdown {
  const { lock, dataUpdatedAt, isLoading } = useLockState(walletId);
  const [now, setNow] = useState(() => Date.now());

  const ticking = lock?.unlocked === true;

  useEffect(() => {
    if (!ticking) return;
    const timer = setInterval(() => setNow(Date.now()), 1_000);
    return () => clearInterval(timer);
  }, [ticking]);

  if (!lock) return { hasSeed: null, unlocked: false, secondsRemaining: 0, isLoading };

  const elapsed = dataUpdatedAt ? Math.floor((now - dataUpdatedAt) / 1000) : 0;
  const secondsRemaining = Math.max(0, lock.secondsRemaining - Math.max(0, elapsed));

  return {
    hasSeed: lock.hasSeed,
    unlocked: lock.unlocked && secondsRemaining > 0,
    secondsRemaining,
    isLoading,
  };
}
