/**
 * 国际化格式化工具
 * I18n Formatting Utilities
 */

import type { Locale } from '@/locales';

/**
 * Locale 到标准语言代码的映射
 */
const localeMap: Record<Locale, string> = {
  zh: 'zh-CN',
  en: 'en-US',
};

/**
 * 格式化日期
 * @param date - 日期对象或字符串
 * @param locale - 语言
 * @param options - Intl.DateTimeFormat 选项
 * @returns 格式化后的日期字符串
 * 
 * @example
 * formatDate(new Date(), 'zh') // "2025年11月21日"
 * formatDate(new Date(), 'en') // "November 21, 2025"
 */
export function formatDate(
  date: Date | string,
  locale: Locale = 'zh',
  options: Intl.DateTimeFormatOptions = {}
): string {
  const dateObj = typeof date === 'string' ? new Date(date) : date;
  
  const defaultOptions: Intl.DateTimeFormatOptions = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    ...options,
  };
  
  return new Intl.DateTimeFormat(localeMap[locale], defaultOptions).format(dateObj);
}

/**
 * 格式化日期时间
 * @param date - 日期对象或字符串
 * @param locale - 语言
 * @param options - Intl.DateTimeFormat 选项
 * @returns 格式化后的日期时间字符串
 * 
 * @example
 * formatDateTime(new Date(), 'zh') // "2025年11月21日 14:30:00"
 * formatDateTime(new Date(), 'en') // "November 21, 2025, 2:30:00 PM"
 */
export function formatDateTime(
  date: Date | string,
  locale: Locale = 'zh',
  options: Intl.DateTimeFormatOptions = {}
): string {
  const dateObj = typeof date === 'string' ? new Date(date) : date;
  
  const defaultOptions: Intl.DateTimeFormatOptions = {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    ...options,
  };
  
  return new Intl.DateTimeFormat(localeMap[locale], defaultOptions).format(dateObj);
}

/**
 * 格式化相对时间（如：2小时前）
 * @param date - 日期对象或字符串
 * @param locale - 语言
 * @returns 格式化后的相对时间字符串
 * 
 * @example
 * formatRelativeTime(new Date(Date.now() - 3600000), 'zh') // "1小时前"
 * formatRelativeTime(new Date(Date.now() - 3600000), 'en') // "1 hour ago"
 */
export function formatRelativeTime(
  date: Date | string,
  locale: Locale = 'zh'
): string {
  const dateObj = typeof date === 'string' ? new Date(date) : date;
  const now = new Date();
  const diffMs = now.getTime() - dateObj.getTime();
  const diffSec = Math.floor(diffMs / 1000);
  const diffMin = Math.floor(diffSec / 60);
  const diffHour = Math.floor(diffMin / 60);
  const diffDay = Math.floor(diffHour / 24);
  const diffMonth = Math.floor(diffDay / 30);
  const diffYear = Math.floor(diffDay / 365);
  
  const rtf = new Intl.RelativeTimeFormat(localeMap[locale], { numeric: 'auto' });
  
  if (Math.abs(diffSec) < 60) return rtf.format(-diffSec, 'second');
  if (Math.abs(diffMin) < 60) return rtf.format(-diffMin, 'minute');
  if (Math.abs(diffHour) < 24) return rtf.format(-diffHour, 'hour');
  if (Math.abs(diffDay) < 30) return rtf.format(-diffDay, 'day');
  if (Math.abs(diffMonth) < 12) return rtf.format(-diffMonth, 'month');
  return rtf.format(-diffYear, 'year');
}

/**
 * 格式化数字
 * @param value - 数字值
 * @param locale - 语言
 * @param options - Intl.NumberFormat 选项
 * @returns 格式化后的数字字符串
 * 
 * @example
 * formatNumber(1234567.89, 'zh') // "1,234,567.89"
 * formatNumber(1234567.89, 'en') // "1,234,567.89"
 */
export function formatNumber(
  value: number,
  locale: Locale = 'zh',
  options: Intl.NumberFormatOptions = {}
): string {
  return new Intl.NumberFormat(localeMap[locale], options).format(value);
}

/**
 * 格式化货币
 * @param value - 数字值
 * @param locale - 语言
 * @param currency - 货币代码 (CNY, USD, EUR, etc.)
 * @returns 格式化后的货币字符串
 * 
 * @example
 * formatCurrency(1234.56, 'zh', 'CNY') // "¥1,234.56"
 * formatCurrency(1234.56, 'en', 'USD') // "$1,234.56"
 */
export function formatCurrency(
  value: number,
  locale: Locale = 'zh',
  currency: string = 'CNY'
): string {
  return new Intl.NumberFormat(localeMap[locale], {
    style: 'currency',
    currency,
  }).format(value);
}

/**
 * 格式化百分比
 * @param value - 数字值（0-100）
 * @param locale - 语言
 * @param decimals - 小数位数
 * @returns 格式化后的百分比字符串
 * 
 * @example
 * formatPercent(75.5, 'zh') // "75.5%"
 * formatPercent(75.5, 'en', 2) // "75.50%"
 */
export function formatPercent(
  value: number,
  locale: Locale = 'zh',
  decimals: number = 0
): string {
  return new Intl.NumberFormat(localeMap[locale], {
    style: 'percent',
    minimumFractionDigits: decimals,
    maximumFractionDigits: decimals,
  }).format(value / 100);
}

/**
 * 格式化紧凑数字（如：1.2K, 3.5M）
 * @param value - 数字值
 * @param locale - 语言
 * @returns 格式化后的紧凑数字字符串
 * 
 * @example
 * formatCompactNumber(1234, 'zh') // "1234"
 * formatCompactNumber(12345, 'zh') // "1.2万"
 * formatCompactNumber(12345, 'en') // "12K"
 */
export function formatCompactNumber(
  value: number,
  locale: Locale = 'zh'
): string {
  return new Intl.NumberFormat(localeMap[locale], {
    notation: 'compact',
    compactDisplay: 'short',
  }).format(value);
}

/**
 * 动态消息格式化（支持变量替换）
 * 
 * @param template - 模板字符串，使用 {变量名} 作为占位符
 * @param values - 变量值对象
 * @returns 格式化后的消息字符串
 * 
 * @example
 * formatMessage('Hello, {name}!', { name: 'John' }) // "Hello, John!"
 * formatMessage('你好，{name}！', { name: '张三' }) // "你好，张三！"
 */
export function formatMessage(
  template: string,
  values: Record<string, string | number> = {}
): string {
  return template.replace(/\{(\w+)\}/g, (match, key) => {
    return key in values ? String(values[key]) : match;
  });
}

/**
 * 复数形式处理
 * 
 * @param count - 数量
 * @param singular - 单数形式
 * @param plural - 复数形式
 * @param locale - 语言
 * @returns 格式化后的字符串
 * 
 * @example
 * pluralize(1, 'item', 'items', 'en') // "1 item"
 * pluralize(2, 'item', 'items', 'en') // "2 items"
 * pluralize(1, '个项目', '个项目', 'zh') // "1个项目"
 */
export function pluralize(
  count: number,
  singular: string,
  plural: string,
  locale: Locale = 'zh'
): string {
  // 中文没有复数形式
  if (locale === 'zh') {
    return `${count}${singular}`;
  }
  
  return `${count} ${count === 1 ? singular : plural}`;
}

/**
 * 格式化文件大小
 * @param bytes - 字节数
 * @param locale - 语言
 * @returns 格式化后的文件大小字符串
 * 
 * @example
 * formatFileSize(1024, 'zh') // "1 KB"
 * formatFileSize(1048576, 'zh') // "1 MB"
 */
export function formatFileSize(
  bytes: number,
  locale: Locale = 'zh'
): string {
  const units = locale === 'zh' 
    ? ['字节', 'KB', 'MB', 'GB', 'TB']
    : ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  
  if (bytes === 0) return `0 ${units[0]}`;
  if (bytes < 1024) return `${bytes} ${units[0]}`;
  
  const k = 1024;
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  const value = bytes / Math.pow(k, i);
  
  return `${value.toFixed(2)} ${units[i]}`;
}

/**
 * 格式化时长（毫秒转换为可读格式）
 * @param ms - 毫秒数
 * @param locale - 语言
 * @returns 格式化后的时长字符串
 * 
 * @example
 * formatDuration(3661000, 'zh') // "1小时1分钟"
 * formatDuration(3661000, 'en') // "1 hour 1 minute"
 */
export function formatDuration(
  ms: number,
  locale: Locale = 'zh'
): string {
  const seconds = Math.floor(ms / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  
  const units = locale === 'zh'
    ? { day: '天', hour: '小时', minute: '分钟', second: '秒' }
    : { day: ' day', hour: ' hour', minute: ' minute', second: ' second' };
  
  const parts: string[] = [];
  
  if (days > 0) {
    parts.push(`${days}${units.day}${locale === 'en' && days > 1 ? 's' : ''}`);
  }
  if (hours % 24 > 0) {
    parts.push(`${hours % 24}${units.hour}${locale === 'en' && hours % 24 > 1 ? 's' : ''}`);
  }
  if (minutes % 60 > 0) {
    parts.push(`${minutes % 60}${units.minute}${locale === 'en' && minutes % 60 > 1 ? 's' : ''}`);
  }
  if (seconds % 60 > 0 && parts.length === 0) {
    parts.push(`${seconds % 60}${units.second}${locale === 'en' && seconds % 60 > 1 ? 's' : ''}`);
  }
  
  return parts.join(locale === 'zh' ? '' : ' ') || `0${units.second}${locale === 'en' ? 's' : ''}`;
}

/**
 * 格式化日期范围
 * @param startDate - 开始日期
 * @param endDate - 结束日期
 * @param locale - 语言
 * @returns 格式化后的日期范围字符串
 * 
 * @example
 * formatDateRange(new Date('2025-01-01'), new Date('2025-01-31'), 'zh')
 * // "2025年1月1日 - 2025年1月31日"
 */
export function formatDateRange(
  startDate: Date | string,
  endDate: Date | string,
  locale: Locale = 'zh'
): string {
  const start = formatDate(startDate, locale);
  const end = formatDate(endDate, locale);
  
  const separator = locale === 'zh' ? ' - ' : ' - ';
  return `${start}${separator}${end}`;
}

/**
 * 格式化分子/分母比例；分母 ≤ 0 时返回占位（默认 `-`）。
 * 用于"此项不适用"vs"数量为 0"的语义区分。
 */
export function formatRatio(
  num: number,
  denom: number,
  fallback: string = '-',
): string {
  return denom > 0 ? `${num}/${denom}` : fallback;
}
