import { useState, useEffect, useCallback } from 'react'
import { api } from '../services/api'
import { logger } from '../utils/logger'

export function useAuth() {
  const [isLoggedIn, setIsLoggedIn] = useState(false)
  const [token, setToken] = useState<string>('')
  const [currentUserId, setCurrentUserId] = useState<number | null>(null)
  const [currentUserName, setCurrentUserName] = useState<string>('')

  // 退出登录函数
  const handleLogout = useCallback(() => {
    localStorage.removeItem('auth_token')
    localStorage.removeItem('user_id')
    localStorage.removeItem('user_name')
    
    setToken('')
    setIsLoggedIn(false)
    setCurrentUserId(null)
    setCurrentUserName('')
    
    logger.info('App: User logged out')
  }, [])

  // 应用启动时检查是否有保存的 token，尝试自动登录
  useEffect(() => {
    const savedToken = localStorage.getItem('auth_token')
    const savedUserId = localStorage.getItem('user_id')
    const savedUserName = localStorage.getItem('user_name')
    
    logger.info('useAuth: Checking for saved token on app start', {
      hasToken: !!savedToken,
      tokenLength: savedToken?.length || 0,
      savedUserId,
      savedUserName,
      isLoggedIn
    })
    
    if (savedToken && !isLoggedIn) {
      const validateAndLogin = async () => {
        logger.info('useAuth: Starting auto login validation', {
          tokenLength: savedToken.length,
          tokenPrefix: savedToken.substring(0, 20) + '...'
        })
        
        try {
          const userInfo = await api.getCurrentUserInfo(savedToken)
          if (userInfo) {
            logger.info('useAuth: Auto login validation successful', {
              userId: userInfo.id,
              hasUserInfo: true
            })
            
            setToken(savedToken)
            setIsLoggedIn(true)
            
            if (userInfo.id) {
              setCurrentUserId(userInfo.id)
              logger.info('useAuth: Set user ID from userInfo', { userId: userInfo.id })
            } else if (savedUserId) {
              const userId = parseInt(savedUserId, 10)
              setCurrentUserId(userId)
              logger.info('useAuth: Set user ID from saved value', { userId })
            }
            
            const userName = userInfo.name || userInfo.full_name || userInfo.username || userInfo.english_name || savedUserName || ''
            if (userName) {
              setCurrentUserName(userName)
              logger.info('useAuth: Set user name', { userName })
            }
            
            logger.info('useAuth: Auto login successful', { 
              userId: userInfo.id || savedUserId,
              userName
            })
          } else {
            logger.warn('useAuth: Auto login failed, token invalid - no user info returned')
            localStorage.removeItem('auth_token')
            localStorage.removeItem('user_id')
            localStorage.removeItem('user_name')
          }
        } catch (error) {
          logger.warn('useAuth: Auto login failed, token invalid or expired', {
            error: error instanceof Error ? {
              name: error.name,
              message: error.message,
              stack: error.stack
            } : String(error)
          })
          localStorage.removeItem('auth_token')
          localStorage.removeItem('user_id')
          localStorage.removeItem('user_name')
        }
      }
      
      validateAndLogin()
    } else {
      if (!savedToken) {
        logger.info('useAuth: No saved token found, skipping auto login')
      } else if (isLoggedIn) {
        logger.info('useAuth: Already logged in, skipping auto login')
      }
    }
  }, [isLoggedIn])

  // 全局错误处理：当 API 返回 401 时自动退出登录
  useEffect(() => {
    if (!isLoggedIn) return
    
    const originalFetch = window.fetch
    window.fetch = async (...args) => {
      const response = await originalFetch(...args)
      
      if (response.status === 401 && isLoggedIn) {
        logger.warn('App: Received 401 unauthorized, logging out')
        localStorage.removeItem('auth_token')
        localStorage.removeItem('user_id')
        localStorage.removeItem('user_name')
        setToken('')
        setIsLoggedIn(false)
        setCurrentUserId(null)
        setCurrentUserName('')
      }
      
      return response
    }
    
    return () => {
      window.fetch = originalFetch
    }
  }, [isLoggedIn])

  // 登录处理函数
  const handleLogin = useCallback(async (accessToken: string, user?: { id: number; [key: string]: any }) => {
    logger.info('useAuth: handleLogin called', {
      hasToken: !!accessToken,
      tokenLength: accessToken.length,
      tokenPrefix: accessToken.substring(0, 20) + '...',
      hasUser: !!user,
      userId: user?.id
    })
    
    setToken(accessToken)
    setIsLoggedIn(true)
    localStorage.setItem('auth_token', accessToken)
    logger.info('useAuth: Token saved to state and localStorage')

    let userId: number | null = null
    let userName: string = ''

    const extractUserName = (userObj: any): string => {
      return userObj?.name || userObj?.full_name || userObj?.username || userObj?.english_name || ''
    }

    if (user?.id) {
      userId = user.id
      userName = extractUserName(user)
      logger.info('useAuth: Got user ID from login response', { userId, userName })
    } else {
      logger.info('useAuth: No user ID in response, trying to extract from token')
      const userIdFromToken = api.getUserIdFromToken(accessToken)
      if (userIdFromToken) {
        userId = userIdFromToken
        logger.info('useAuth: Got user ID from token', { userId })
      } else {
        logger.info('useAuth: Token extraction failed, calling getCurrentUserInfo API')
        try {
          const userInfo = await api.getCurrentUserInfo(accessToken)
          if (userInfo?.id) {
            userId = userInfo.id
            userName = extractUserName(userInfo)
            logger.info('useAuth: Got user ID from API', { userId, userName })
          } else {
            logger.warn('useAuth: Could not get user ID from any source. Some features may not work correctly.', {
              hasUserInfo: !!userInfo
            })
          }
        } catch (error) {
          logger.error('useAuth: Failed to get user info', {
            error: error instanceof Error ? {
              name: error.name,
              message: error.message,
              stack: error.stack
            } : String(error)
          })
        }
      }
    }

    if (userId) {
      setCurrentUserId(userId)
      localStorage.setItem('user_id', userId.toString())
      logger.info('useAuth: User ID saved', { userId })
    }

    if (!userName && userId) {
      logger.info('useAuth: User name not found, trying to get from API')
      try {
        const userInfo = await api.getCurrentUserInfo(accessToken)
        userName = extractUserName(userInfo)
        if (userName) {
          logger.info('useAuth: Got user name from getCurrentUserInfo', { userName })
        } else {
          logger.info('useAuth: getCurrentUserInfo did not return name, trying searchContacts')
          try {
            const searchResults = await api.searchContacts(accessToken, '', 100)
            const currentUser = searchResults.find(u => u.id === userId)
            if (currentUser) {
              userName = currentUser.name || currentUser.english_name || ''
              if (userName) {
                logger.info('useAuth: Got user name from searchContacts', { userName })
              } else {
                logger.warn('useAuth: searchContacts found user but no name field', { userId })
              }
            } else {
              logger.warn('useAuth: searchContacts did not find current user', { userId })
            }
          } catch (searchError) {
            logger.warn('useAuth: Failed to get user name from searchContacts', {
              error: searchError instanceof Error ? {
                name: searchError.name,
                message: searchError.message
              } : String(searchError)
            })
          }
        }
      } catch (error) {
        logger.error('useAuth: Failed to get user name', {
          error: error instanceof Error ? {
            name: error.name,
            message: error.message,
            stack: error.stack
          } : String(error)
        })
      }
    }

    if (userName) {
      setCurrentUserName(userName)
      localStorage.setItem('user_name', userName)
      logger.info('useAuth: User name saved', { userName })
    }
    
    logger.info('useAuth: handleLogin completed', {
      userId,
      userName,
      isLoggedIn: true
    })
  }, [])

  return {
    isLoggedIn,
    token,
    currentUserId,
    currentUserName,
    handleLogin,
    handleLogout
  }
}
