import UpdateDialogPopup from '@renderer/components/Popups/UpdateDialogPopup'
import { NotificationService } from '@renderer/services/NotificationService'
import { useAppDispatch } from '@renderer/store'
import { setUpdateState } from '@renderer/store/runtime'
import { uuid } from '@renderer/utils'
import { IpcChannel } from '@shared/IpcChannel'
import type { ProgressInfo, UpdateInfo } from 'builder-util-runtime'
import { useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'

import { useRuntime } from './useRuntime'

export default function useUpdateHandler() {
  const dispatch = useAppDispatch()
  const { t } = useTranslation()
  const notificationService = NotificationService.getInstance()
  const { update } = useRuntime()
  const manualCheckRef = useRef(update.manualCheck)

  // Keep ref in sync with current state
  useEffect(() => {
    manualCheckRef.current = update.manualCheck
  }, [update.manualCheck])

  useEffect(() => {
    if (!window.electron) return

    const ipcRenderer = window.electron.ipcRenderer

    const removers = [
      ipcRenderer.on(IpcChannel.UpdateNotAvailable, () => {
        dispatch(setUpdateState({ checking: false, manualCheck: false }))
        if (window.location.hash.includes('settings/about')) {
          window.toast.success(t('settings.about.updateNotAvailable'))
        }
      }),
      ipcRenderer.on(IpcChannel.UpdateAvailable, (_, releaseInfo: UpdateInfo) => {
        void notificationService.send({
          id: uuid(),
          type: 'info',
          title: t('button.update_available'),
          message: t('button.update_available', { version: releaseInfo.version }),
          timestamp: Date.now(),
          source: 'update',
          channel: 'system'
        })
        dispatch(
          setUpdateState({
            checking: false,
            downloading: true,
            info: releaseInfo,
            available: true
          })
        )
      }),
      ipcRenderer.on(IpcChannel.DownloadUpdate, () => {
        dispatch(
          setUpdateState({
            checking: false,
            downloading: true
          })
        )
      }),
      ipcRenderer.on(IpcChannel.DownloadProgress, (_, progress: ProgressInfo) => {
        dispatch(
          setUpdateState({
            downloading: progress.percent < 100,
            downloadProgress: progress.percent
          })
        )
      }),
      ipcRenderer.on(IpcChannel.UpdateDownloaded, (_, releaseInfo: UpdateInfo) => {
        dispatch(
          setUpdateState({
            downloading: false,
            info: releaseInfo,
            downloaded: true
          })
        )
        // Auto show update dialog when download completes (only if user manually triggered the check)
        if (manualCheckRef.current) {
          void UpdateDialogPopup.show({ releaseInfo })
        }
      }),
      ipcRenderer.on(IpcChannel.UpdateError, (_, error) => {
        dispatch(
          setUpdateState({
            checking: false,
            downloading: false,
            downloadProgress: 0,
            manualCheck: false
          })
        )
        if (window.location.hash.includes('settings/about')) {
          window.modal.info({
            title: t('settings.about.updateError'),
            content: error?.message || t('settings.about.updateError'),
            icon: null
          })
        }
      })
    ]
    return () => removers.forEach((remover) => remover())
  }, [dispatch, notificationService, t])
}
