// 工具函数
// 依据：project_rules §3.4 TypeScript 规则、§3.9 Tailwind 规范

import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

/**
 * 类名合并工具（project_rules §3.9）
 * 支持条件类名，合并 Tailwind 类
 */
export function cn(...inputs: ClassValue[]): string {
  return twMerge(clsx(inputs));
}

/**
 * 格式化日期（i18n，02 §17.4 国际化格式）
 */
export function formatDate(
  date: string | Date,
  locale: string = "zh-CN",
): string {
  const d = typeof date === "string" ? new Date(date) : date;
  return new Intl.DateTimeFormat(locale, {
    year: "numeric",
    month: "long",
    day: "numeric",
  }).format(d);
}

/**
 * 格式化日期时间
 */
export function formatDateTime(
  date: string | Date,
  locale: string = "zh-CN",
): string {
  const d = typeof date === "string" ? new Date(date) : date;
  return new Intl.DateTimeFormat(locale, {
    year: "numeric",
    month: "short",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(d);
}

/**
 * 格式化相对时间（如"3小时前"）
 */
export function formatRelativeTime(
  date: string | Date,
  locale: string = "zh-CN",
): string {
  const d = typeof date === "string" ? new Date(date) : date;
  const now = Date.now();
  const diff = now - d.getTime();
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
  if (days > 0) return rtf.format(-days, "day");
  if (hours > 0) return rtf.format(-hours, "hour");
  if (minutes > 0) return rtf.format(-minutes, "minute");
  return rtf.format(-seconds, "second");
}

/**
 * 格式化数字（02 §17.4）
 */
export function formatNumber(value: number, locale: string = "zh-CN"): string {
  return new Intl.NumberFormat(locale).format(value);
}

/**
 * 格式化百分比
 */
export function formatPercent(
  value: number,
  locale: string = "zh-CN",
  digits: number = 1,
): string {
  return new Intl.NumberFormat(locale, {
    style: "percent",
    minimumFractionDigits: digits,
    maximumFractionDigits: digits,
  }).format(value);
}

/**
 * 生成唯一 ID（用于客户端临时标识）
 */
export function generateId(): string {
  return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
}

/**
 * 成绩等级映射（02 §17.4）
 */
export function scoreToGrade(score: number, maxScore: number = 100): string {
  const percentage = (score / maxScore) * 100;
  if (percentage >= 90) return "A";
  if (percentage >= 80) return "B";
  if (percentage >= 70) return "C";
  if (percentage >= 60) return "D";
  return "F";
}

/**
 * 成绩等级中文映射
 */
export function gradeToChinese(grade: string): string {
  const map: Record<string, string> = {
    A: "优秀",
    B: "良好",
    C: "及格",
    D: "及格",
    F: "不及格",
  };
  return map[grade] ?? grade;
}

/**
 * 安全获取 localStorage（SSR 安全）
 */
export function getLocalStorage(key: string): string | null {
  if (typeof window === "undefined") return null;
  try {
    return window.localStorage.getItem(key);
  } catch {
    return null;
  }
}

/**
 * 安全设置 localStorage
 */
export function setLocalStorage(key: string, value: string): boolean {
  if (typeof window === "undefined") return false;
  try {
    window.localStorage.setItem(key, value);
    return true;
  } catch {
    return false;
  }
}

/**
 * 安全删除 localStorage
 */
export function removeLocalStorage(key: string): void {
  if (typeof window === "undefined") return;
  try {
    window.localStorage.removeItem(key);
  } catch {
    // 忽略
  }
}

/**
 * 防抖
 */
export function debounce<T extends (...args: never[]) => void>(
  fn: T,
  delay: number,
): (...args: Parameters<T>) => void {
  let timer: ReturnType<typeof setTimeout> | null = null;
  return (...args: Parameters<T>) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

/**
 * 节流
 */
export function throttle<T extends (...args: never[]) => void>(
  fn: T,
  interval: number,
): (...args: Parameters<T>) => void {
  let lastTime = 0;
  return (...args: Parameters<T>) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn(...args);
    }
  };
}

/**
 * 指数退避延迟
 */
export function getBackoffDelay(
  attempt: number,
  baseDelay: number = 1000,
): number {
  return Math.min(baseDelay * Math.pow(2, attempt), 30000);
}

/**
 * 生成 trace_id
 */
export function generateTraceId(): string {
  return `parent-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
}
