/**
 * Auto-updater hook for desktop wallet.
 *
 * Listens to backend events and provides update functionality.
 */

import { useEffect, useState, useCallback } from 'react';
import { listen } from '@tauri-apps/api/event';
import { invoke } from '@tauri-apps/api/core';

export interface UpdateInfo {
  version: string;
  body?: string;
  date?: string;
  downloadUrl?: string;
}

export interface UpdateState {
  checking: boolean;
  available: boolean;
  downloading: boolean;
  installed: boolean;
  error: string | null;
  updateInfo: UpdateInfo | null;
}

export function useAutoUpdater() {
  const [state, setState] = useState<UpdateState>({
    checking: false,
    available: false,
    downloading: false,
    installed: false,
    error: null,
    updateInfo: null,
  });

  // Listen for backend events
  useEffect(() => {
    const unlisteners: (() => void)[] = [];

    // Update available notification from backend
    listen<UpdateInfo>('update-available', (event) => {
      setState((prev) => ({
        ...prev,
        available: true,
        updateInfo: event.payload,
      }));
    }).then((unlisten) => unlisteners.push(unlisten));

    // Update installed notification
    listen('update-installed', () => {
      setState((prev) => ({
        ...prev,
        downloading: false,
        installed: true,
      }));
    }).then((unlisten) => unlisteners.push(unlisten));

    // Check updates trigger from tray
    listen('check-updates', () => {
      checkForUpdates();
    }).then((unlisten) => unlisteners.push(unlisten));

    return () => {
      unlisteners.forEach((unlisten) => unlisten());
    };
  }, []);

  // Check for updates manually
  const checkForUpdates = useCallback(async () => {
    setState((prev) => ({ ...prev, checking: true, error: null }));

    try {
      const result = await invoke<UpdateInfo | null>('check_update');

      if (result) {
        setState((prev) => ({
          ...prev,
          checking: false,
          available: true,
          updateInfo: result,
        }));
      } else {
        setState((prev) => ({
          ...prev,
          checking: false,
          available: false,
          updateInfo: null,
        }));
      }
    } catch (error) {
      setState((prev) => ({
        ...prev,
        checking: false,
        error: error instanceof Error ? error.message : String(error),
      }));
    }
  }, []);

  // Install available update
  const installUpdate = useCallback(async () => {
    if (!state.available) return;

    setState((prev) => ({ ...prev, downloading: true, error: null }));

    try {
      await invoke('install_update');
      // The 'update-installed' event will set the installed state
    } catch (error) {
      setState((prev) => ({
        ...prev,
        downloading: false,
        error: error instanceof Error ? error.message : String(error),
      }));
    }
  }, [state.available]);

  // Dismiss update notification
  const dismissUpdate = useCallback(() => {
    setState((prev) => ({
      ...prev,
      available: false,
      updateInfo: null,
    }));
  }, []);

  return {
    ...state,
    checkForUpdates,
    installUpdate,
    dismissUpdate,
  };
}
