/**
 * 时区工具函数
 */

/**
 * 获取用户系统时区
 * 使用浏览器 API 自动检测用户当前所在时区
 */
export function getUserSystemTimezone(): string {
  try {
    // 使用 Intl API 获取用户系统时区
    const systemTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone
    if (systemTimezone) {
      return systemTimezone
    }
  } catch (error) {
    console.warn('Failed to get user system timezone:', error)
  }
  // 如果获取失败，返回默认时区
  return 'Asia/Shanghai'
}

/**
 * 获取当前设置的时区
 * 优先使用用户保存的时区设置，如果没有则自动获取用户系统时区
 */
export function getCurrentTimezone(): string {
  const savedTimezone = localStorage.getItem('timezone')
  if (savedTimezone) {
    return savedTimezone
  }
  // 如果没有保存的时区，自动获取用户系统时区
  return getUserSystemTimezone()
}

/**
 * 格式化时间到指定时区
 * @param date 日期对象或日期字符串
 * @param timezone 时区，默认使用用户设置的时区
 * @param options 格式化选项
 */
export function formatDateTimeInTimezone(
  date: Date | string | null | undefined,
  timezone?: string,
  options: Intl.DateTimeFormatOptions = {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  }
): string {
  if (!date) return '—'
  
  try {
    const dateObj = typeof date === 'string' ? new Date(date) : date
    const targetTimezone = timezone || getCurrentTimezone()
    
    return new Intl.DateTimeFormat('zh-CN', {
      ...options,
      timeZone: targetTimezone
    }).format(dateObj)
  } catch (error) {
    console.error('Error formatting date:', error)
    return typeof date === 'string' ? date : date?.toString() || '—'
  }
}

/**
 * 格式化日期到指定时区（只显示日期）
 * @param date 日期对象或日期字符串
 * @param timezone 时区，默认使用用户设置的时区
 */
export function formatDateInTimezone(
  date: Date | string | null | undefined,
  timezone?: string
): string {
  return formatDateTimeInTimezone(date, timezone, {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit'
  })
}

/**
 * 格式化时间到指定时区（只显示时间）
 * @param date 日期对象或日期字符串
 * @param timezone 时区，默认使用用户设置的时区
 */
export function formatTimeInTimezone(
  date: Date | string | null | undefined,
  timezone?: string
): string {
  return formatDateTimeInTimezone(date, timezone, {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false
  })
}

/**
 * 获取时区偏移信息（简化高效版本）
 * @param timezone 时区
 */
export function getTimezoneOffset(timezone: string): string {
  try {
    const now = new Date()
    // 使用 Intl API 直接获取偏移量，更高效
    const formatter = new Intl.DateTimeFormat('en-US', {
      timeZone: timezone,
      timeZoneName: 'shortOffset'
    })
    const parts = formatter.formatToParts(now)
    const offsetPart = parts.find(part => part.type === 'timeZoneName')
    
    if (offsetPart?.value) {
      // 格式化为标准 UTC+08:00 格式
      const offset = offsetPart.value.replace('GMT', 'UTC')
      return offset.startsWith('UTC') ? offset : `UTC${offset}`
    }
    
    // 降级方案：手动计算
    const utcTime = now.getTime() + (now.getTimezoneOffset() * 60000)
    const localTime = new Date(now.toLocaleString('en-US', { timeZone: timezone }))
    const offset = (localTime.getTime() - utcTime) / 3600000
    
    const sign = offset >= 0 ? '+' : '-'
    const hours = Math.abs(Math.floor(offset))
    const minutes = Math.abs((offset % 1) * 60)
    
    return `UTC${sign}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`
  } catch (error) {
    return 'UTC+00:00'
  }
}

/**
 * 获取时区的友好显示名称（符合业内最佳实践）
 * @param timezone 时区标识符
 * @param offset UTC 偏移量（可选，避免重复计算）
 */
function getTimezoneDisplayName(timezone: string, offset?: string): string {
  try {
    // 获取 UTC 偏移量（如果未提供则计算）
    const timezoneOffset = offset || getTimezoneOffset(timezone)
    
    // 业内最佳实践格式：洲/城市 (UTC+08:00)
    // 例如：Asia/Shanghai (UTC+08:00)
    // 优点：包含完整IANA时区标识符，避免同名城市混淆，符合标准
    return `${timezone} (${timezoneOffset})`
  } catch (error) {
    return timezone
  }
}

// 缓存时区选项，避免重复计算
let cachedTimezoneOptions: Array<{ label: string; value: string }> | null = null
let cachedGroupedTimezoneOptions: Array<{ type: string; label: string; key: string; children: Array<{ label: string; value: string }> }> | null = null

/**
 * 获取所有标准的 IANA 时区列表（带缓存，高效实现）
 * 使用浏览器标准的 Intl API 获取所有支持的时区，覆盖所有国家
 * @returns 时区选项数组，包含 label 和 value
 * @throws 如果浏览器不支持 Intl.supportedValuesOf，抛出错误
 */
export function getAllTimezoneOptions(): Array<{ label: string; value: string }> {
  // 返回缓存的结果，避免重复计算
  if (cachedTimezoneOptions) {
    return cachedTimezoneOptions
  }

  // 检查浏览器是否支持 Intl.supportedValuesOf API
  if (typeof Intl === 'undefined' || !('supportedValuesOf' in Intl)) {
    throw new Error(
      'Browser does not support Intl.supportedValuesOf API. ' +
      'This indicates an implementation issue. ' +
      'Please use a modern browser that supports ECMAScript Intl API.'
    )
  }

  try {
    // 使用标准的 Intl.supportedValuesOf API 获取所有支持的时区
    const timezones = (Intl as any).supportedValuesOf('timeZone') as string[]
    
    if (!timezones || timezones.length === 0) {
      throw new Error('Failed to get timezone list from Intl.supportedValuesOf')
    }
    
    // 对时区进行排序：UTC 优先，然后按偏移量排序，最后按地区分组
    const timezoneData = timezones.map(timezone => {
      const offset = getTimezoneOffset(timezone)
      // 提取偏移量数值用于排序
      const offsetMatch = offset.match(/UTC([+-])(\d{2}):(\d{2})/)
      const offsetValue = offsetMatch
        ? (offsetMatch[1] === '+' ? 1 : -1) * (parseInt(offsetMatch[2]) * 60 + parseInt(offsetMatch[3]))
        : 0
      
      return { timezone, offset, offsetValue }
    })
    
    // 排序：UTC 优先，然后按偏移量，最后按地区
    timezoneData.sort((a, b) => {
      if (a.timezone === 'UTC') return -1
      if (b.timezone === 'UTC') return 1
      
      // 按偏移量排序
      if (a.offsetValue !== b.offsetValue) {
        return a.offsetValue - b.offsetValue
      }
      
      // 相同偏移量按地区分组
      const aRegion = a.timezone.split('/')[0]
      const bRegion = b.timezone.split('/')[0]
      if (aRegion !== bRegion) {
        return aRegion.localeCompare(bRegion)
      }
      
      // 同一地区内按城市名排序
      return a.timezone.localeCompare(b.timezone)
    })
    
    // 生成选项列表（传递 offset 避免重复计算）
    cachedTimezoneOptions = timezoneData.map(({ timezone, offset }) => ({
      label: getTimezoneDisplayName(timezone, offset),
      value: timezone
    }))
    
    return cachedTimezoneOptions
  } catch (error) {
    throw new Error(
      `Failed to get timezone options: ${error instanceof Error ? error.message : String(error)}. ` +
      'This indicates an implementation issue.'
    )
  }
}

/**
 * 获取分组的时区选项（符合业内最佳实践）
 * 按 UTC 偏移量分组，便于用户快速找到相同时区的不同城市
 * @returns 分组的时区选项数组，适用于支持分组的 UI 组件
 */
export function getGroupedTimezoneOptions(): Array<{ type: string; label: string; key: string; children: Array<{ label: string; value: string }> }> {
  // 返回缓存的结果
  if (cachedGroupedTimezoneOptions) {
    return cachedGroupedTimezoneOptions
  }

  // 先获取所有时区选项（这会填充缓存）
  const allOptions = getAllTimezoneOptions()
  
  // 分离 UTC 和其他时区
  const utcOptions: Array<{ label: string; value: string }> = []
  const otherOptions: Array<{ label: string; value: string }> = []
  
  allOptions.forEach(option => {
    if (option.value === 'UTC') {
      utcOptions.push(option)
    } else {
      otherOptions.push(option)
    }
  })
  
  // 按 UTC 偏移量分组
  const grouped = new Map<string, Array<{ label: string; value: string }>>()
  
  otherOptions.forEach(option => {
    // 从 label 中提取 UTC 偏移量，格式：Asia/Shanghai (UTC+08:00)
    const offsetMatch = option.label.match(/\((UTC[+-]\d{2}:\d{2})\)$/)
    const offset = offsetMatch ? offsetMatch[1] : 'UTC+00:00'
    
    if (!grouped.has(offset)) {
      grouped.set(offset, [])
    }
    grouped.get(offset)!.push(option)
  })
  
  // 对每个分组内的时区按字母顺序排序
  grouped.forEach((children) => {
    children.sort((a, b) => {
      // 提取时区标识符进行比较（去掉 UTC 偏移量后缀）
      // 格式：Asia/Shanghai (UTC+08:00)
      const aTimezone = a.label.replace(/\s+\(UTC[+-]\d{2}:\d{2}\)$/, '')
      const bTimezone = b.label.replace(/\s+\(UTC[+-]\d{2}:\d{2}\)$/, '')
      return aTimezone.localeCompare(bTimezone)
    })
  })
  
  // 转换为分组格式，按偏移量排序（从负到正）
  const offsetGroups = Array.from(grouped.entries())
    .sort((a, b) => {
      // 提取偏移量数值用于排序
      const aMatch = a[0].match(/UTC([+-])(\d{2}):(\d{2})/)
      const bMatch = b[0].match(/UTC([+-])(\d{2}):(\d{2})/)
      const aValue = aMatch
        ? (aMatch[1] === '+' ? 1 : -1) * (parseInt(aMatch[2]) * 60 + parseInt(aMatch[3]))
        : 0
      const bValue = bMatch
        ? (bMatch[1] === '+' ? 1 : -1) * (parseInt(bMatch[2]) * 60 + parseInt(bMatch[3]))
        : 0
      return aValue - bValue
    })
    .map(([offset, children]) => ({
      type: 'group',
      label: offset,
      key: offset,
      children
    }))
  
  // UTC 单独作为第一个分组（如果有）
  const result: Array<{ type: string; label: string; key: string; children: Array<{ label: string; value: string }> }> = []
  
  if (utcOptions.length > 0) {
    result.push({
      type: 'group',
      label: 'UTC',
      key: 'UTC',
      children: utcOptions
    })
  }
  
  result.push(...offsetGroups)
  
  cachedGroupedTimezoneOptions = result
  return cachedGroupedTimezoneOptions
}
