/**
 * Private Gallery Authentication Hook
 *
 * Manages authentication state for the private gallery:
 * - Session token stored in memory (not localStorage for security)
 * - Auto-lock after timeout
 * - Status checking
 */

import { useState, useEffect, useCallback, useRef } from 'react'
import { api } from '../lib/api'

export interface PrivateGalleryAuthState {
  isLoading: boolean
  isSetupComplete: boolean
  isUnlocked: boolean
  error: string | null
}

export interface UsePrivateGalleryAuthResult extends PrivateGalleryAuthState {
  setup: (password: string) => Promise<boolean>
  unlock: (password: string) => Promise<boolean>
  lock: () => Promise<void>
  changePassword: (currentPassword: string, newPassword: string) => Promise<boolean>
  refreshStatus: () => Promise<void>
  clearError: () => void
}

export function usePrivateGalleryAuth(): UsePrivateGalleryAuthResult {
  const [state, setState] = useState<PrivateGalleryAuthState>({
    isLoading: true,
    isSetupComplete: false,
    isUnlocked: false,
    error: null,
  })

  const refreshTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // Check current status
  const refreshStatus = useCallback(async () => {
    try {
      const status = await api.privateGallery.getStatus()
      setState(prev => ({
        ...prev,
        isLoading: false,
        isSetupComplete: status.is_setup_complete,
        isUnlocked: status.is_unlocked,
        error: null,
      }))
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Failed to check status',
      }))
    }
  }, [])

  // Initial status check
  useEffect(() => {
    refreshStatus()
  }, [refreshStatus])

  // Schedule periodic status refresh when unlocked (for auto-lock detection)
  useEffect(() => {
    if (state.isUnlocked) {
      // Refresh every 30 seconds to detect auto-lock
      refreshTimeoutRef.current = setInterval(() => {
        refreshStatus()
      }, 30 * 1000)

      return () => {
        if (refreshTimeoutRef.current) {
          clearInterval(refreshTimeoutRef.current)
        }
      }
    }
  }, [state.isUnlocked, refreshStatus])

  // Check status when tab becomes visible (user returns to page)
  useEffect(() => {
    const handleVisibilityChange = () => {
      if (document.visibilityState === 'visible' && state.isUnlocked) {
        refreshStatus()
      }
    }

    document.addEventListener('visibilitychange', handleVisibilityChange)
    return () => document.removeEventListener('visibilitychange', handleVisibilityChange)
  }, [state.isUnlocked, refreshStatus])

  // Check status on window focus (another way user returns)
  useEffect(() => {
    const handleFocus = () => {
      if (state.isUnlocked) {
        refreshStatus()
      }
    }

    window.addEventListener('focus', handleFocus)
    return () => window.removeEventListener('focus', handleFocus)
  }, [state.isUnlocked, refreshStatus])

  const setup = useCallback(async (password: string): Promise<boolean> => {
    setState(prev => ({ ...prev, isLoading: true, error: null }))
    try {
      await api.privateGallery.setup(password)
      setState(prev => ({
        ...prev,
        isLoading: false,
        isSetupComplete: true,
        isUnlocked: true,
      }))
      return true
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Setup failed',
      }))
      return false
    }
  }, [])

  const unlock = useCallback(async (password: string): Promise<boolean> => {
    setState(prev => ({ ...prev, isLoading: true, error: null }))
    try {
      await api.privateGallery.unlock(password)
      setState(prev => ({
        ...prev,
        isLoading: false,
        isUnlocked: true,
      }))
      return true
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Invalid password',
      }))
      return false
    }
  }, [])

  const lock = useCallback(async (): Promise<void> => {
    try {
      await api.privateGallery.lock()
    } catch {
      // Ignore errors - clear local state anyway
    }
    api.setPrivateGalleryToken(null)
    setState(prev => ({
      ...prev,
      isUnlocked: false,
    }))
  }, [])

  const changePassword = useCallback(async (currentPassword: string, newPassword: string): Promise<boolean> => {
    setState(prev => ({ ...prev, isLoading: true, error: null }))
    try {
      await api.privateGallery.changePassword(currentPassword, newPassword)
      setState(prev => ({ ...prev, isLoading: false }))
      return true
    } catch (err) {
      setState(prev => ({
        ...prev,
        isLoading: false,
        error: err instanceof Error ? err.message : 'Failed to change password',
      }))
      return false
    }
  }, [])

  const clearError = useCallback(() => {
    setState(prev => ({ ...prev, error: null }))
  }, [])

  return {
    ...state,
    setup,
    unlock,
    lock,
    changePassword,
    refreshStatus,
    clearError,
  }
}

export default usePrivateGalleryAuth
