import { useUserStore } from '@/stores/user'
import { message, Modal } from 'ant-design-vue'
import router from '@/router'
import envConfig from '@/config/env'

// API基础配置
const API_CONFIG = {
  baseURL: envConfig.baseURL,
  timeout: envConfig.timeout
}

// 是否正在刷新token的标志
let isRefreshing = false
// 存储待重试的请求
let failedQueue = []

// 请求缓存
const requestCache = new Map()
const CACHE_DURATION = 5 * 60 * 1000 // 5分钟缓存

// 处理队列中的请求
const processQueue = (error, token = null) => {
  failedQueue.forEach(({ resolve, reject }) => {
    if (error) {
      reject(error)
    } else {
      resolve(token)
    }
  })
  
  failedQueue = []
}

// 生成缓存键
const generateCacheKey = (url, options) => {
  return `${url}_${JSON.stringify(options)}`
}

// 检查缓存
const checkCache = (cacheKey) => {
  const cached = requestCache.get(cacheKey)
  if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
    return cached.data
  }
  return null
}

// 设置缓存
const setCache = (cacheKey, data) => {
  requestCache.set(cacheKey, {
    data,
    timestamp: Date.now()
  })
}

/**
 * 创建请求头
 * @param {Object} customHeaders - 自定义请求头
 * @returns {Object} 请求头对象
 */
const createHeaders = (customHeaders = {}) => {
  const userStore = useUserStore()
  const token = userStore.accessToken || localStorage.getItem('accessToken')
  
  const defaultHeaders = {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Cache-Control': 'no-cache',
    'Pragma': 'no-cache'
  }
  
  if (token) {
    defaultHeaders['Authorization'] = `Bearer ${token}`
  }
  
  return { ...defaultHeaders, ...customHeaders }
}

/**
 * 处理fetch响应
 * @param {Response} response - fetch响应对象
 * @returns {Promise} 处理后的响应数据
 */
const handleResponse = async (response) => {
  let data
  
  try {
    const contentType = response.headers.get('content-type')
    
    // 处理文件下载（Excel、CSV等）
    if (contentType && (
      contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') ||
      contentType.includes('text/csv') ||
      contentType.includes('application/octet-stream')
    )) {
      data = await response.blob()
    } else if (contentType && contentType.includes('application/json')) {
      data = await response.json()
    } else {
      data = await response.text()
    }
  } catch (error) {
    data = null
  }
  
  if (!response.ok) {
    const error = new Error(data?.message || `HTTP ${response.status}: ${response.statusText}`)
    error.response = {
      status: response.status,
      statusText: response.statusText,
      data: data
    }
    throw error
  }
  
  return { data, status: response.status, statusText: response.statusText }
}

/**
 * 基于fetch的请求方法
 * @param {string} url - 请求URL
 * @param {Object} options - 请求选项
 * @returns {Promise} 请求结果
 */
const fetchRequest = async (url, options = {}) => {
  const userStore = useUserStore()
  
  // 处理查询参数
  let finalUrl = url.startsWith('http') ? url : `${API_CONFIG.baseURL}${url}`
  
  if (options.params) {
    const searchParams = new URLSearchParams()
    Object.keys(options.params).forEach(key => {
      if (options.params[key] !== undefined && options.params[key] !== null) {
        searchParams.append(key, options.params[key])
      }
    })
    
    const queryString = searchParams.toString()
    if (queryString) {
      finalUrl += (finalUrl.includes('?') ? '&' : '?') + queryString
    }
    
    // 从options中移除params，避免传递给fetch
    delete options.params
  }
  
  // 构建完整URL
  const fullUrl = finalUrl
  
  // 对于登录、刷新token接口，跳过token检查
  const skipTokenCheck = url.includes('/auth/login') || 
                        url.includes('/auth/refresh') ||
                        url.includes('/auth/register')
  
  if (!skipTokenCheck) {
    try {
      // 确保token有效（自动刷新如果需要）
      const validToken = await userStore.ensureValidToken()
      
      if (validToken) {
        options.headers = {
          ...options.headers,
          'Authorization': `Bearer ${validToken}`
        }
      }
    } catch (error) {
      console.error('获取有效token失败:', error)
      // 如果无法获取有效token，继续发送请求，让响应处理器处理
    }
  }
  
  // 设置默认请求头
  options.headers = createHeaders(options.headers)
  
  // ========== 请求前日志 ==========
  try {
    const hasAuth = !!options.headers?.Authorization
    const contentType = options.headers?.['Content-Type']
    const acceptType = options.headers?.['Accept']
    let bodyPreview = null
    if (options.body) {
      try {
        bodyPreview = JSON.stringify(JSON.parse(options.body))
      } catch (_) {
        bodyPreview = String(options.body).slice(0, 1000)
      }
    }
    console.log('🔶 [前端] 准备发起请求', {
      method: options.method || 'GET',
      url: fullUrl,
      hasAuthorization: hasAuth ? '是' : '否',
      contentType,
      acceptType,
      bodyPreview
    })
  } catch (logError) {
    console.warn('记录请求前日志失败:', logError)
  }
  
  // 设置超时
  const controller = new AbortController()
  const timeoutId = setTimeout(() => controller.abort(), API_CONFIG.timeout)
  options.signal = controller.signal
  
  try {
    const response = await fetch(fullUrl, options)
    clearTimeout(timeoutId)
    
    // ========== 原始响应日志 ==========
    try {
      console.log('🟩 [前端] 收到原始响应', {
        status: response.status,
        statusText: response.statusText,
        url: fullUrl,
        ok: response.ok,
        contentType: response.headers.get('content-type')
      })
    } catch (respLogErr) {
      console.warn('记录原始响应日志失败:', respLogErr)
    }
    
    const result = await handleResponse(response)
    
    // ========== 处理后响应日志 ==========
    try {
      const safeData = (() => {
        try {
          return typeof result.data === 'string' ? result.data.slice(0, 1000) : JSON.stringify(result.data).slice(0, 1000)
        } catch (_) {
          return '[不可序列化数据]'
        }
      })()
      console.log('✅ [前端] 请求成功', {
        url: fullUrl,
        method: options.method || 'GET',
        status: result.status,
        statusText: result.statusText,
        dataPreview: safeData
      })
    } catch (resLogErr) {
      console.warn('记录处理后响应日志失败:', resLogErr)
    }
    
    return result
  } catch (error) {
    clearTimeout(timeoutId)
    
    // ========== 错误日志 ==========
    try {
      console.error('❌ [前端] 请求失败', {
        url: fullUrl,
        method: options.method || 'GET',
        message: error.message,
        name: error.name,
        responseStatus: error.response?.status,
        responseDataPreview: (() => {
          try {
            return JSON.stringify(error.response?.data).slice(0, 1000)
          } catch (_) {
            return String(error.response?.data || '')
          }
        })()
      })
    } catch (errLogErr) {
      console.warn('记录错误日志失败:', errLogErr)
    }
    
    // 处理401错误
    if (error.response?.status === 401) {
      const errorCode = error.response?.data?.code
      
      // 如果是token过期错误
      if (errorCode === 'TOKEN_EXPIRED') {
        // 如果已经在刷新token，将请求加入队列
        if (isRefreshing) {
          return new Promise((resolve, reject) => {
            failedQueue.push({ resolve, reject })
          }).then(token => {
            options.headers['Authorization'] = `Bearer ${token}`
            return fetchRequest(url, options)
          }).catch(err => {
            return Promise.reject(err)
          })
        }
        
        isRefreshing = true
        
        try {
          // 尝试刷新token
          const newToken = await userStore.refreshAccessToken()
          
          // 处理队列中的请求
          processQueue(null, newToken)
          
          // 重试原始请求
          options.headers['Authorization'] = `Bearer ${newToken}`
          return fetchRequest(url, options)
        } catch (refreshError) {
          // 刷新失败，处理队列并跳转到登录页
          processQueue(refreshError, null)
          
          message.error('登录已过期，请重新登录')
          
          // 清除用户信息
          userStore.logout()
          
          // 跳转到登录页
          if (router.currentRoute.value.path !== '/login') {
            router.push('/login')
          }
          
          return Promise.reject(refreshError)
        } finally {
          isRefreshing = false
        }
      } else {
        // 其他401错误（如token无效），直接跳转登录页
        message.error('认证失败，请重新登录')
        userStore.logout()
        
        if (router.currentRoute.value.path !== '/login') {
          router.push('/login')
        }
      }
    }
    
    // 处理其他错误
    if (error.response?.data?.message) {
      message.error(error.response.data.message)
    } else if (error.message && !error.message.includes('aborted')) {
      message.error(error.message)
    }
    
    throw error
  }
}

/**
 * 创建类似axios的API接口
 */
const request = {
  get: (url, config = {}) => {
    return fetchRequest(url, {
      method: 'GET',
      ...config
    })
  },
  
  post: (url, data = null, config = {}) => {
    return fetchRequest(url, {
      method: 'POST',
      body: data ? JSON.stringify(data) : null,
      ...config
    })
  },
  
  put: (url, data = null, config = {}) => {
    return fetchRequest(url, {
      method: 'PUT',
      body: data ? JSON.stringify(data) : null,
      ...config
    })
  },
  
  delete: (url, config = {}) => {
    return fetchRequest(url, {
      method: 'DELETE',
      ...config
    })
  },
  
  patch: (url, data = null, config = {}) => {
    return fetchRequest(url, {
      method: 'PATCH',
      body: data ? JSON.stringify(data) : null,
      ...config
    })
  }
}

// 自动重新登录功能
export const autoRelogin = async (username, password) => {
  try {
    const response = await request.post('/auth/login', {
      username,
      password
    })
    
    if (response.data.success) {
      const userStore = useUserStore()
      userStore.setAuthData(response.data.data)
      
      message.success('自动重新登录成功')
      return true
    }
  } catch (error) {
    console.error('自动重新登录失败:', error)
    message.error('自动重新登录失败，请手动登录')
  }
  
  return false
}

// Token过期提醒
export const setupTokenExpirationWarning = () => {
  const userStore = useUserStore()
  
  // 每分钟检查一次token状态
  setInterval(() => {
    if (userStore.isTokenExpiringSoon && !userStore.isTokenExpired) {
      // Token即将过期，显示提醒
      Modal.confirm({
        title: '登录提醒',
        content: '您的登录即将过期，是否继续保持登录状态？',
        okText: '继续登录',
        cancelText: '退出登录',
        onOk: async () => {
          try {
            await userStore.refreshAccessToken()
            message.success('登录状态已延长')
          } catch (error) {
            message.error('刷新登录状态失败')
            userStore.logout()
            router.push('/login')
          }
        },
        onCancel: () => {
          userStore.logout()
          router.push('/login')
        }
      })
    }
  }, 60000) // 每分钟检查一次
}

// 导出默认的请求实例和别名
export default request
export const apiClient = request