// API 工具函数文件
import type { ApiResponse, PaginationResponse } from './types'

/**
 * 构建查询参数字符串
 */
export const buildQueryString = (params: Record<string, any>): string => {
  const searchParams = new URLSearchParams()
  
  Object.keys(params).forEach(key => {
    const value = params[key]
    if (value !== undefined && value !== null && value !== '') {
      if (Array.isArray(value)) {
        value.forEach(item => searchParams.append(key, String(item)))
      } else {
        searchParams.append(key, String(value))
      }
    }
  })
  
  return searchParams.toString()
}

/**
 * 构建完整的URL
 */
export const buildUrl = (baseUrl: string, endpoint: string, params?: Record<string, any>): string => {
  let url = `${baseUrl}${endpoint}`
  
  if (params) {
    const queryString = buildQueryString(params)
    if (queryString) {
      url += `?${queryString}`
    }
  }
  
  return url
}

/**
 * 替换URL中的路径参数
 */
export const replaceUrlParams = (url: string, params: Record<string, string | number>): string => {
  let result = url
  
  Object.keys(params).forEach(key => {
    result = result.replace(`:${key}`, String(params[key]))
  })
  
  return result
}

/**
 * 检查API响应是否成功
 */
export const isApiSuccess = (response: ApiResponse): boolean => {
  return response.code === 200 || response.code === 0
}

/**
 * 提取API响应数据
 */
export const extractApiData = <T>(response: ApiResponse<T>): T => {
  if (isApiSuccess(response)) {
    return response.data
  }
  throw new Error(response.message || 'API请求失败')
}

/**
 * 格式化分页数据
 */
export const formatPaginationData = <T>(response: ApiResponse<PaginationResponse<T>>) => {
  if (isApiSuccess(response)) {
    const { list, total, page, pageSize, totalPages } = response.data
    return {
      items: list,
      total,
      currentPage: page,
      pageSize,
      totalPages: totalPages || Math.ceil(total / pageSize),
      hasNext: page < (totalPages || Math.ceil(total / pageSize)),
      hasPrev: page > 1,
    }
  }
  throw new Error(response.message || '获取分页数据失败')
}

/**
 * 创建分页参数
 */
export const createPaginationParams = (page: number = 1, pageSize: number = 20) => {
  return {
    page: Math.max(1, page),
    pageSize: Math.min(Math.max(1, pageSize), 100), // 限制最大页面大小
  }
}

/**
 * 防抖函数 - 用于搜索等场景
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let timeout: NodeJS.Timeout | null = null
  
  return (...args: Parameters<T>) => {
    if (timeout) {
      clearTimeout(timeout)
    }
    
    timeout = setTimeout(() => {
      func(...args)
    }, wait)
  }
}

/**
 * 节流函数 - 用于频繁触发的事件
 */
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  wait: number
): ((...args: Parameters<T>) => void) => {
  let lastTime = 0
  
  return (...args: Parameters<T>) => {
    const now = Date.now()
    
    if (now - lastTime >= wait) {
      lastTime = now
      func(...args)
    }
  }
}

/**
 * 重试函数 - 用于网络请求重试
 */
export const retry = async <T>(
  fn: () => Promise<T>,
  maxAttempts: number = 3,
  delay: number = 1000
): Promise<T> => {
  let lastError: Error
  
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await fn()
    } catch (error) {
      lastError = error as Error
      
      if (attempt === maxAttempts) {
        throw lastError
      }
      
      // 指数退避延迟
      const waitTime = delay * Math.pow(2, attempt - 1)
      await new Promise(resolve => setTimeout(resolve, waitTime))
    }
  }
  
  throw lastError!
}

/**
 * 格式化文件大小
 */
export const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

/**
 * 格式化时间
 */
export const formatDuration = (seconds: number): string => {
  if (seconds < 60) {
    return `${Math.round(seconds)}秒`
  } else if (seconds < 3600) {
    const minutes = Math.floor(seconds / 60)
    const remainingSeconds = Math.round(seconds % 60)
    return remainingSeconds > 0 ? `${minutes}分${remainingSeconds}秒` : `${minutes}分钟`
  } else {
    const hours = Math.floor(seconds / 3600)
    const minutes = Math.floor((seconds % 3600) / 60)
    return minutes > 0 ? `${hours}小时${minutes}分钟` : `${hours}小时`
  }
}

/**
 * 验证邮箱格式
 */
export const isValidEmail = (email: string): boolean => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return emailRegex.test(email)
}

/**
 * 验证手机号格式（中国大陆）
 */
export const isValidPhone = (phone: string): boolean => {
  const phoneRegex = /^1[3-9]\d{9}$/
  return phoneRegex.test(phone)
}

/**
 * 验证密码强度
 */
export const validatePassword = (password: string): {
  isValid: boolean
  strength: 'weak' | 'medium' | 'strong'
  issues: string[]
} => {
  const issues: string[] = []
  let score = 0
  
  if (password.length < 8) {
    issues.push('密码长度至少8位')
  } else {
    score += 1
  }
  
  if (!/[a-z]/.test(password)) {
    issues.push('密码需包含小写字母')
  } else {
    score += 1
  }
  
  if (!/[A-Z]/.test(password)) {
    issues.push('密码需包含大写字母')
  } else {
    score += 1
  }
  
  if (!/\d/.test(password)) {
    issues.push('密码需包含数字')
  } else {
    score += 1
  }
  
  if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
    issues.push('密码需包含特殊字符')
  } else {
    score += 1
  }
  
  let strength: 'weak' | 'medium' | 'strong'
  if (score < 3) {
    strength = 'weak'
  } else if (score < 5) {
    strength = 'medium'
  } else {
    strength = 'strong'
  }
  
  return {
    isValid: issues.length === 0,
    strength,
    issues
  }
}

/**
 * 生成随机字符串
 */
export const generateRandomString = (length: number = 8): string => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let result = ''
  
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  
  return result
}

/**
 * 深拷贝对象
 */
export const deepClone = <T>(obj: T): T => {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  
  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T
  }
  
  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as unknown as T
  }
  
  if (typeof obj === 'object') {
    const cloned = {} as T
    Object.keys(obj).forEach(key => {
      (cloned as any)[key] = deepClone((obj as any)[key])
    })
    return cloned
  }
  
  return obj
}

/**
 * 获取错误消息
 */
export const getErrorMessage = (error: any): string => {
  if (typeof error === 'string') {
    return error
  }
  
  if (error?.response?.data?.message) {
    return error.response.data.message
  }
  
  if (error?.message) {
    return error.message
  }
  
  return '未知错误'
}

/**
 * 本地存储工具
 */
export const storage = {
  get: <T>(key: string, defaultValue?: T): T | null => {
    try {
      const item = localStorage.getItem(key)
      return item ? JSON.parse(item) : defaultValue || null
    } catch {
      return defaultValue || null
    }
  },
  
  set: (key: string, value: any): void => {
    try {
      localStorage.setItem(key, JSON.stringify(value))
    } catch (error) {
      console.error('存储数据失败:', error)
    }
  },
  
  remove: (key: string): void => {
    try {
      localStorage.removeItem(key)
    } catch (error) {
      console.error('删除存储数据失败:', error)
    }
  },
  
  clear: (): void => {
    try {
      localStorage.clear()
    } catch (error) {
      console.error('清空存储数据失败:', error)
    }
  }
}
