import { useState, useCallback, useEffect } from 'react'
import { invoke } from '@tauri-apps/api/core'
import { listen } from '@tauri-apps/api/event'
import { ActionType } from '@/components/buttons/ActionButton'
import { Game, DlcInfo } from '@/types'
import { InstallationInstructions } from '@/contexts/AppContext'
import { useUnlockerSelection } from './useUnlockerSelection'

/**
 * Hook for managing game action operations
 * Handles installation, uninstallation, and progress tracking
 */
export function useGameActions() {
  // Progress dialog state
  const [progressDialog, setProgressDialog] = useState({
    visible: false,
    title: '',
    message: '',
    progress: 0,
    showInstructions: false,
    instructions: undefined as InstallationInstructions | undefined,
  })

  // Set up event listeners for progress updates
  useEffect(() => {
    const setupEventListeners = async () => {
      try {
        // Listen for progress updates from the backend
        const unlistenProgress = await listen<{
          title: string
          message: string
          progress: number
          complete: boolean
          show_instructions?: boolean
          instructions?: InstallationInstructions
        }>('installation-progress', (event) => {
          console.log('Received installation-progress event:', event)

          const { title, message, progress, complete, show_instructions, instructions } =
            event.payload

          if (complete && !show_instructions) {
            // Hide dialog when complete if no instructions
            setTimeout(() => {
              setProgressDialog((prev) => ({ ...prev, visible: false }))
            }, 1000)
          } else {
            // Update progress dialog
            setProgressDialog({
              visible: true,
              title,
              message,
              progress,
              showInstructions: show_instructions || false,
              instructions,
            })
          }
        })

        return unlistenProgress
      } catch (error) {
        console.error('Error setting up progress event listeners:', error)
        return () => {}
      }
    }

    let cleanup: (() => void) | null = null

    setupEventListeners().then((unlisten) => {
      cleanup = unlisten
    })

    return () => {
      if (cleanup) cleanup()
    }
  }, [])

  // Handler function to close progress dialog
  const handleCloseProgressDialog = useCallback(() => {
    setProgressDialog((prev) => ({ ...prev, visible: false }))
  }, [])

  // Unlocker selection hook for native games
  const {
    selectionState,
    showUnlockerSelection,
    handleSelectCreamLinux,
    handleSelectSmokeAPI,
    closeDialog: closeUnlockerDialog,
  } = useUnlockerSelection()

  // Unified handler for game actions (install/uninstall)
  const handleGameAction = useCallback(
    async (gameId: string, action: ActionType, games: Game[]) => {
      try {
        // Find the game
        const game = games.find((g) => g.id === gameId)
        if (!game) return

        // For CreamLinux installation, DLC dialog is handled in AppProvider
        if (action === 'install_cream') {
          return
        }

        // Handle generic "install_unlocker" action for native games
        if (action === 'install_unlocker') {
          showUnlockerSelection(game, (chosenAction: ActionType) => {
            // User chose, now proceed with that action
            handleGameAction(gameId, chosenAction, games)
          })
          return
        }

        // For other actions (uninstall_cream, install_smoke, uninstall_smoke)
        const isCream = action.includes('cream')
        const isInstall = action.includes('install')
        const product = isCream ? 'CreamLinux' : 'SmokeAPI'
        const operation = isInstall ? 'Installing' : 'Uninstalling'

        // Show progress dialog
        setProgressDialog({
          visible: true,
          title: `${operation} ${product} for ${game.title}`,
          message: isInstall ? 'Downloading required files...' : 'Removing files...',
          progress: isInstall ? 0 : 30,
          showInstructions: false,
          instructions: undefined,
        })

        console.log(`Invoking process_game_action for game ${gameId} with action ${action}`)

        // Call the backend with the unified action
        await invoke('process_game_action', {
          gameAction: {
            game_id: gameId,
            action,
          },
        })
      } catch (error) {
        console.error(`Error processing action ${action} for game ${gameId}:`, error)

        // Show error in progress dialog
        setProgressDialog((prev) => ({
          ...prev,
          message: `Error: ${error}`,
          progress: 100,
        }))

        // Hide dialog after a delay
        setTimeout(() => {
          setProgressDialog((prev) => ({ ...prev, visible: false }))
        }, 3000)

        // Rethrow to allow upstream handling
        throw error
      }
    },
    [showUnlockerSelection]
  )

  // Handle DLC selection confirmation
  const handleDlcConfirm = useCallback(
    async (selectedDlcs: DlcInfo[], gameId: string, isEditMode: boolean, games: Game[]) => {
      // Find the game
      const game = games.find((g) => g.id === gameId)
      if (!game) return

      try {
        if (isEditMode) {
          // Create a deep copy to ensure we don't have reference issues
          const dlcsCopy = selectedDlcs.map((dlc) => ({ ...dlc }))

          // Show progress dialog for editing
          setProgressDialog({
            visible: true,
            title: `Updating DLCs for ${game.title}`,
            message: 'Updating DLC configuration...',
            progress: 30,
            showInstructions: false,
            instructions: undefined,
          })

          console.log('Saving DLC configuration:', dlcsCopy)

          // Call the backend to update the DLC configuration
          await invoke('update_dlc_configuration_command', {
            gamePath: game.path,
            dlcs: dlcsCopy,
          })

          // Update progress dialog for completion
          setProgressDialog((prev) => ({
            ...prev,
            title: `Update Complete: ${game.title}`,
            message: 'DLC configuration updated successfully!',
            progress: 100,
          }))

          // Hide dialog after a delay
          setTimeout(() => {
            setProgressDialog((prev) => ({ ...prev, visible: false }))
          }, 2000)
        } else {
          // We're doing a fresh install with selected DLCs
          // Show progress dialog for installation right away
          setProgressDialog({
            visible: true,
            title: `Installing CreamLinux for ${game.title}`,
            message: 'Preparing to download CreamLinux...',
            progress: 0,
            showInstructions: false,
            instructions: undefined,
          })

          // Invoke the installation with the selected DLCs
          await invoke('install_cream_with_dlcs_command', {
            gameId,
            selectedDlcs,
          })

          // The progress dialog will be updated through the installation-progress event listener
        }
      } catch (error) {
        console.error('Error processing DLC selection:', error)

        // Show error in progress dialog
        setProgressDialog((prev) => ({
          ...prev,
          message: `Error: ${error}`,
          progress: 100,
        }))

        // Hide dialog after a delay
        setTimeout(() => {
          setProgressDialog((prev) => ({ ...prev, visible: false }))
        }, 3000)

        // Rethrow to allow upstream handling
        throw error
      }
    },
    []
  )

  return {
    progressDialog,
    setProgressDialog,
    handleCloseProgressDialog,
    handleGameAction,
    handleDlcConfirm,
    unlockerSelectionDialog: selectionState,
    handleSelectCreamLinux,
    handleSelectSmokeAPI,
    closeUnlockerDialog,
  }
}
