export { authApi } from './auth'
export { userApi } from './user'

// 默认导出request实例，方便其他地方使用
export { default as request } from './request'

// ===========================================

// src/store/modules/auth.js - 认证状态管理
import { authApi } from '@/api/auth'
import { ElMessage } from 'element-plus'

const state = {
  // 登录状态
  isLoggedIn: false,
  // 用户信息
  userInfo: null,
  // Token信息
  token: null,
  // 登录加载状态
  loginLoading: false
}

const getters = {
  // 是否已登录
  isAuthenticated: state => state.isLoggedIn,
  // 获取用户信息
  userInfo: state => state.userInfo,
  // 获取用户名
  username: state => state.userInfo?.user?.username || '',
  // 获取用户头像
  avatar: state => state.userInfo?.user?.avatar || '',
  // 获取用户组信息
  userGroup: state => state.userInfo?.user?.group || null,
  // 登录加载状态
  loginLoading: state => state.loginLoading
}

const mutations = {
  // 设置登录状态
  SET_LOGIN_STATUS(state, status) {
    state.isLoggedIn = status
  },
  
  // 设置用户信息
  SET_USER_INFO(state, userInfo) {
    state.userInfo = userInfo
  },
  
  // 设置Token
  SET_TOKEN(state, token) {
    state.token = token
  },
  
  // 设置登录加载状态
  SET_LOGIN_LOADING(state, loading) {
    state.loginLoading = loading
  },
  
  // 清除用户数据
  CLEAR_USER_DATA(state) {
    state.isLoggedIn = false
    state.userInfo = null
    state.token = null
    state.loginLoading = false
  }
}

const actions = {
  // 用户登录
  async login({ commit }, loginData) {
    try {
      commit('SET_LOGIN_LOADING', true)
      
      const response = await authApi.login(loginData)
      
      if (response) {
        // 保存Token
        const tokenInfo = response.token
        if (tokenInfo && tokenInfo.tokenValue) {
          localStorage.setItem('token', tokenInfo.tokenValue)
          localStorage.setItem('tokenInfo', JSON.stringify(tokenInfo))
          commit('SET_TOKEN', tokenInfo)
        }
        
        // 保存用户信息
        localStorage.setItem('userInfo', JSON.stringify(response))
        localStorage.setItem('isLoggedIn', 'true')
        
        commit('SET_USER_INFO', response)
        commit('SET_LOGIN_STATUS', true)
        
        ElMessage.success('登录成功！')
        return response
      }
    } catch (error) {
      console.error('登录失败:', error)
      throw error
    } finally {
      commit('SET_LOGIN_LOADING', false)
    }
  },
  
  // 用户注册
  async register({ commit }, registerData) {
    try {
      commit('SET_LOGIN_LOADING', true)
      
      const response = await authApi.register(registerData)
      
      if (response) {
        // 注册成功后自动登录
        const tokenInfo = response.token
        if (tokenInfo && tokenInfo.tokenValue) {
          localStorage.setItem('token', tokenInfo.tokenValue)
          localStorage.setItem('tokenInfo', JSON.stringify(tokenInfo))
          commit('SET_TOKEN', tokenInfo)
        }
        
        localStorage.setItem('userInfo', JSON.stringify(response))
        localStorage.setItem('isLoggedIn', 'true')
        
        commit('SET_USER_INFO', response)
        commit('SET_LOGIN_STATUS', true)
        
        ElMessage.success('注册成功！')
        return response
      }
    } catch (error) {
      console.error('注册失败:', error)
      throw error
    } finally {
      commit('SET_LOGIN_LOADING', false)
    }
  },
  
  // 用户登出
  async logout({ commit }) {
    try {
      await authApi.logout()
    } catch (error) {
      console.error('登出请求失败:', error)
      // 即使登出请求失败，也要清除本地数据
    } finally {
      // 清除本地存储
      localStorage.removeItem('token')
      localStorage.removeItem('tokenInfo')
      localStorage.removeItem('userInfo')
      localStorage.removeItem('isLoggedIn')
      
      // 清除状态
      commit('CLEAR_USER_DATA')
      
      ElMessage.success('已退出登录')
    }
  },
  
  // 检查登录状态
  async checkLoginStatus({ commit }) {
    try {
      const response = await authApi.getStatus()
      
      if (response && response.isLoggedIn && response.user) {
        // 更新用户信息
        localStorage.setItem('userInfo', JSON.stringify(response.user))
        localStorage.setItem('isLoggedIn', 'true')
        
        commit('SET_USER_INFO', response.user)
        commit('SET_LOGIN_STATUS', true)
        
        return true
      } else {
        // 登录状态无效，清除本地数据
        commit('CLEAR_USER_DATA')
        localStorage.removeItem('token')
        localStorage.removeItem('tokenInfo')
        localStorage.removeItem('userInfo')
        localStorage.removeItem('isLoggedIn')
        
        return false
      }
    } catch (error) {
      console.error('检查登录状态失败:', error)
      commit('CLEAR_USER_DATA')
      return false
    }
  },
  
  // 从本地存储恢复登录状态
  restoreLoginState({ commit }) {
    const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'
    const userInfo = localStorage.getItem('userInfo')
    const tokenInfo = localStorage.getItem('tokenInfo')
    
    if (isLoggedIn && userInfo) {
      try {
        const parsedUserInfo = JSON.parse(userInfo)
        const parsedTokenInfo = tokenInfo ? JSON.parse(tokenInfo) : null
        
        commit('SET_USER_INFO', parsedUserInfo)
        commit('SET_TOKEN', parsedTokenInfo)
        commit('SET_LOGIN_STATUS', true)
        
        console.log('✅ 已从本地存储恢复登录状态')
      } catch (error) {
        console.error('❌ 恢复登录状态失败:', error)
        commit('CLEAR_USER_DATA')
      }
    }
  }
}

export default {
  namespaced: true,
  state,
  getters,
  mutations,
  actions
}