/**
 * 格式化工具函数
 */

/**
 * 格式化流量（MB -> GB/MB）
 * @param mb 流量（MB）
 * @param decimal 保留小数位数
 */
export function formatFlow(mb: number | undefined, decimal = 2): string {
  if (mb === undefined || mb === null) return '-'

  if (mb >= 1024) {
    return `${(mb / 1024).toFixed(decimal)} GB`
  }
  return `${mb.toFixed(decimal)} MB`
}

/**
 * 格式化金额（分 -> 元）
 * @param fen 金额（分）
 * @param showSymbol 是否显示货币符号
 */
export function formatMoney(fen: number | undefined, showSymbol = true): string {
  if (fen === undefined || fen === null) return '-'

  const yuan = (fen / 100).toFixed(2)
  return showSymbol ? `¥${yuan}` : yuan
}

export function fenToYuan(fen: number | undefined | null): number {
  if (fen === undefined || fen === null || Number.isNaN(fen)) return 0

  return Number((fen / 100).toFixed(2))
}

export function yuanToFen(yuan: number | undefined | null): number | undefined {
  if (yuan === undefined || yuan === null || Number.isNaN(yuan)) return undefined

  return Math.round(yuan * 100)
}

/**
 * 格式化手机号（中间4位隐藏）
 * @param phone 手机号
 */
export function formatPhone(phone: string | undefined): string {
  if (!phone) return '-'

  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

/**
 * 格式化ICCID（显示前5位和后4位）
 * @param iccid ICCID
 */
export function formatIccid(iccid: string | undefined): string {
  if (!iccid) return '-'

  if (iccid.length > 10) {
    return `${iccid.substring(0, 5)}...${iccid.substring(iccid.length - 4)}`
  }
  return iccid
}

/**
 * 格式化ICCID（完整显示，带分隔符）
 * @param iccid ICCID
 */
export function formatIccidFull(iccid: string | undefined): string {
  if (!iccid) return '-'

  // 每4位添加一个空格
  return iccid.replace(/(\d{4})(?=\d)/g, '$1 ')
}

/**
 * 格式化百分比
 * @param value 数值
 * @param total 总数
 * @param decimal 保留小数位数
 */
export function formatPercentage(
  value: number | undefined,
  total: number | undefined,
  decimal = 2
): string {
  if (value === undefined || total === undefined || total === 0) return '-'

  const percentage = ((value / total) * 100).toFixed(decimal)
  return `${percentage}%`
}

/**
 * 格式化时长（秒 -> 时分秒）
 * @param seconds 秒数
 */
export function formatDuration(seconds: number | undefined): string {
  if (seconds === undefined || seconds === null) return '-'

  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  const secs = seconds % 60

  const parts: string[] = []
  if (hours > 0) parts.push(`${hours}时`)
  if (minutes > 0) parts.push(`${minutes}分`)
  if (secs > 0 || parts.length === 0) parts.push(`${secs}秒`)

  return parts.join('')
}

/**
 * 格式化文件大小
 * @param bytes 字节数
 * @param decimal 保留小数位数
 */
export function formatFileSize(bytes: number | undefined, decimal = 2): string {
  if (bytes === undefined || bytes === null) return '-'

  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let size = bytes
  let unitIndex = 0

  while (size >= 1024 && unitIndex < units.length - 1) {
    size /= 1024
    unitIndex++
  }

  return `${size.toFixed(decimal)} ${units[unitIndex]}`
}

/**
 * 格式化数字（添加千分位）
 * @param num 数字
 */
export function formatNumber(num: number | undefined): string {
  if (num === undefined || num === null) return '-'

  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

/**
 * 隐藏银行卡号（显示前4位和后4位）
 * @param cardNo 银行卡号
 */
export function formatBankCard(cardNo: string | undefined): string {
  if (!cardNo) return '-'

  if (cardNo.length > 8) {
    const stars = '*'.repeat(cardNo.length - 8)
    return `${cardNo.substring(0, 4)} ${stars} ${cardNo.substring(cardNo.length - 4)}`
  }
  return cardNo
}

/**
 * 格式化日期范围
 * @param startDate 开始日期
 * @param endDate 结束日期
 */
export function formatDateRange(startDate: string, endDate: string): string {
  if (!startDate || !endDate) return '-'

  return `${startDate} ~ ${endDate}`
}

/**
 * 格式化日期时间
 * 规则：
 * 1. 带明确日期文本的字符串按原始时间文本展示，不跟随客户端本地时区转换
 * 2. 纯数字时间戳支持秒/毫秒自动识别
 * 3. Date/时间戳这类“只有绝对时刻、没有原始展示时区”的值，按 UTC 稳定输出
 * @param date 日期字符串或时间戳（支持 Unix 时间戳秒/毫秒，自动检测）
 * @param format 格式化模板，默认 'YYYY-MM-DD HH:mm:ss'
 * @returns 格式化后的日期字符串
 */
type DateTimeParts = {
  year: string
  month: string
  day: string
  hours: string
  minutes: string
  seconds: string
}

const DATE_TIME_TEXT_REGEX =
  /^(\d{4})-(\d{2})-(\d{2})(?:[T\s](\d{2})(?::(\d{2})(?::(\d{2})(?:\.\d+)?)?)?)?(?:Z|[+-]\d{2}:?\d{2})?$/

function formatDateTimeParts(parts: DateTimeParts, format: string): string {
  return format
    .replace('YYYY', parts.year)
    .replace('MM', parts.month)
    .replace('DD', parts.day)
    .replace('HH', parts.hours)
    .replace('mm', parts.minutes)
    .replace('ss', parts.seconds)
}

function parseDateTimeText(dateText: string): DateTimeParts | null {
  const match = dateText.trim().match(DATE_TIME_TEXT_REGEX)
  if (!match) return null

  return {
    year: match[1],
    month: match[2],
    day: match[3],
    hours: match[4] ?? '00',
    minutes: match[5] ?? '00',
    seconds: match[6] ?? '00'
  }
}

function normalizeTimestamp(timestamp: number): number {
  const absoluteValue = Math.abs(timestamp)

  // 10 位左右按秒处理，13 位左右按毫秒处理
  if (absoluteValue >= 1e9 && absoluteValue < 1e12) {
    return timestamp * 1000
  }

  return timestamp
}

function getUtcDateTimeParts(date: Date): DateTimeParts {
  return {
    year: String(date.getUTCFullYear()),
    month: String(date.getUTCMonth() + 1).padStart(2, '0'),
    day: String(date.getUTCDate()).padStart(2, '0'),
    hours: String(date.getUTCHours()).padStart(2, '0'),
    minutes: String(date.getUTCMinutes()).padStart(2, '0'),
    seconds: String(date.getUTCSeconds()).padStart(2, '0')
  }
}

export function formatDateTime(
  date: string | number | Date | undefined | null,
  format: string = 'YYYY-MM-DD HH:mm:ss'
): string {
  if (date === undefined || date === null || date === '') return '-'

  if (typeof date === 'string') {
    const trimmedDate = date.trim()
    if (!trimmedDate) return '-'

    const parsedText = parseDateTimeText(trimmedDate)
    if (parsedText) {
      return formatDateTimeParts(parsedText, format)
    }

    const numericTimestamp = Number(trimmedDate)
    if (!Number.isNaN(numericTimestamp)) {
      const parsedDate = new Date(normalizeTimestamp(numericTimestamp))
      if (Number.isNaN(parsedDate.getTime())) return '-'
      return formatDateTimeParts(getUtcDateTimeParts(parsedDate), format)
    }
  }

  const parsedDate = new Date(typeof date === 'number' ? normalizeTimestamp(date) : date)
  if (Number.isNaN(parsedDate.getTime())) return '-'

  return formatDateTimeParts(getUtcDateTimeParts(parsedDate), format)
}

/**
 * 格式化费率（基点 -> 百分比）
 * @param basisPoints 费率基点（100基点=1%）
 * @param decimal 保留小数位数
 */
export function formatFeeRate(basisPoints: number | undefined, decimal = 2): string {
  if (basisPoints === undefined || basisPoints === null) return '-'

  const percentage = (basisPoints / 100).toFixed(decimal)
  return `${percentage}%`
}
