import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'
//test
const request = axios.create({
  // 关键：不要设置baseURL，或者设置为空字符串
  // 这样请求会发送到当前域名（8080），然后被代理转发到8081
  baseURL: process.env.VUE_APP_BASE_API || '',
  timeout: 10000,
  headers: {
    // 'Content-Type': 'application/json'
  }
})

request.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token')
    console.log('📤 Token长度:', token ? token.length : 0)
    console.log('📤 Token前50字符:', token ? token.substring(0, 50) + '...' : 'null')
    
    if (token) {
      // 检查token是否过大
      if (token.length > 8000) {
        console.warn('⚠️ Token过大，长度:', token.length)
        // 清除过大的token
        localStorage.removeItem('token')
        localStorage.removeItem('tokenInfo')
        localStorage.removeItem('userInfo')
        localStorage.removeItem('isLoggedIn')
        ElMessage.error('登录信息过大，请重新登录')
        router.push('/login')
        return Promise.reject(new Error('Token过大'))
      }
      config.headers.Authorization = `Bearer ${token}`
    }
    
    console.log('🚀 发送请求:', config.method?.toUpperCase(), config.url)
    console.log('📤 请求数据:', config.data)
    
    return config
  },
  error => {
    console.error('❌ 请求错误:', error)
    return Promise.reject(error)
  }
)

request.interceptors.response.use(
  response => {
    console.log('✅ 响应成功:', response.status, response.data)
    return response.data
  },
  error => {
    console.error('❌ 响应错误:', error)
    
    if (error.response) {
      const { status, data } = error.response
      
      switch (status) {
        case 401:
          localStorage.removeItem('token')
          localStorage.removeItem('isLoggedIn') 
          localStorage.removeItem('userInfo')
          ElMessage.error('登录已过期，请重新登录')
          router.push('/login')
          break
        case 403:
          ElMessage.error('权限不足')
          break
        case 404:
          ElMessage.error('API接口不存在')
          console.error('❌ 请求的URL:', error.config.url)
          break
        case 431:
          console.error('❌ 请求头太大 (431)，可能是Token过大')
          localStorage.removeItem('token')
          localStorage.removeItem('tokenInfo')
          localStorage.removeItem('userInfo')
          localStorage.removeItem('isLoggedIn')
          ElMessage.error('登录信息过大，请重新登录')
          router.push('/login')
          break
        case 500:
          ElMessage.error('服务器内部错误')
          break
        default:
          const errorMessage = data?.message || `请求失败 (${status})`
          ElMessage.error(errorMessage)
      }
    } else if (error.request) {
      ElMessage.error('无法连接到服务器，请检查网络')
    } else {
      ElMessage.error('请求配置错误')
    }
    
    return Promise.reject(error)
  }
)

export default request