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>('')
  /** 启动时本地有 auth_token，正在请求 /users/me 校验；校验结束前不展示登录表单 */
  const [isRestoringSession, setIsRestoringSession] = useState(
    () => typeof localStorage !== 'undefined' && !!localStorage.getItem('auth_token')
  )
  /** 会话恢复失败（过期/无效）时在登录页展示的提示 */
  const [sessionExpiredMessage, setSessionExpiredMessage] = useState('')

  // 退出登录函数
  const handleLogout = useCallback(() => {
    // 退出登录时清空消息中心未读，避免切换账号后仍显示上个账号的未读
    if (window.electron && window.electron.ipcRenderer) {
      window.electron.ipcRenderer.send('clear-all-unread')
    }
    localStorage.removeItem('auth_token')
    localStorage.removeItem('user_id')
    localStorage.removeItem('user_name')
    
    setToken('')
    setIsLoggedIn(false)
    setCurrentUserId(null)
    setCurrentUserName('')
    setSessionExpiredMessage('')
    
    logger.info('App: User logged out')
  }, [])

  // 应用启动时仅执行一次：若有保存的 token，用 /users/me 校验后再决定进入主界面或登录页
  useEffect(() => {
    const savedToken = localStorage.getItem('auth_token')
    const savedUserId = localStorage.getItem('user_id')
    const savedUserName = localStorage.getItem('user_name')

    if (!savedToken) {
      logger.info('useAuth: No saved token on mount, skip session restore')
      return
    }

    let cancelled = false

    const validateAndLogin = async () => {
      logger.info('useAuth: Starting session restore (validate token via /users/me)', {
        tokenLength: savedToken.length,
        tokenPrefix: savedToken.substring(0, 20) + '...'
      })

      try {
        const userInfo = await api.getCurrentUserInfo(savedToken)
        if (cancelled) return

        if (userInfo) {
          setSessionExpiredMessage('')
          logger.info('useAuth: Session restore 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: Session restore successful', {
            userId: userInfo.id || savedUserId,
            userName
          })

          if (window.electron?.ipcRenderer) {
            window.electron.ipcRenderer.send('login-success')
            logger.info('useAuth: Sent login-success to main process (session restore)')
          }
        } else {
          logger.warn('useAuth: Session restore failed, token invalid - no user info returned')
          localStorage.removeItem('auth_token')
          localStorage.removeItem('user_id')
          localStorage.removeItem('user_name')
          setSessionExpiredMessage('身份已过期，请重新登录')
        }
      } catch (error) {
        if (cancelled) return
        logger.warn('useAuth: Session restore 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')
        setSessionExpiredMessage('身份已过期，请重新登录')
      } finally {
        if (!cancelled) {
          setIsRestoringSession(false)
        }
      }
    }

    validateAndLogin()
    return () => {
      cancelled = true
    }
  }, [])

  // 全局错误处理：当 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('')
        setSessionExpiredMessage('登录已过期，请重新登录')
      }
      
      return response
    }
    
    return () => {
      window.fetch = originalFetch
    }
  }, [isLoggedIn])

  // 登录处理函数
  const handleLogin = useCallback(async (accessToken: string, user?: { id: number; [key: string]: any }) => {
    setSessionExpiredMessage('')

    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,
    isRestoringSession,
    sessionExpiredMessage
  }
}
