import { useState, useCallback } from 'react';

type TauriInternals = { invoke: (cmd: string, args?: Record<string, unknown>) => Promise<unknown> };
const tauriInvoke = (): TauriInternals['invoke'] | undefined =>
  (window as unknown as { __TAURI_INTERNALS__?: TauriInternals }).__TAURI_INTERNALS__?.invoke;

type UpdateStatus =
  | { state: 'idle' }
  | { state: 'checking' }
  | { state: 'up-to-date' }
  | { state: 'available'; version: string }
  | { state: 'installing' }
  | { state: 'error'; message: string };

export function useTauriUpdater() {
  const isTauri = !!tauriInvoke();
  const [status, setStatus] = useState<UpdateStatus>({ state: 'idle' });

  const check = useCallback(async () => {
    const invoke = tauriInvoke();
    if (!invoke) return;
    setStatus({ state: 'checking' });
    try {
      const result = (await invoke('check_for_update')) as { available: boolean; version?: string };
      setStatus(
        result.available && result.version
          ? { state: 'available', version: result.version }
          : { state: 'up-to-date' },
      );
    } catch (e) {
      setStatus({ state: 'error', message: String(e) });
    }
  }, []);

  const install = useCallback(async () => {
    const invoke = tauriInvoke();
    if (!invoke) return;
    setStatus({ state: 'installing' });
    try {
      await invoke('install_update');
      // On a successful install the native side calls app.restart(), so this
      // resolve is only reached when nothing was installed (no update found) —
      // don't leave the UI stuck on "installing".
      setStatus({ state: 'up-to-date' });
    } catch (e) {
      setStatus({ state: 'error', message: String(e) });
    }
  }, []);

  return { isTauri, status, check, install };
}
