/**
 * 诚裕集团企业官网 - 工具函数
 */

/**
 * 日期格式化函数
 * @param dateString - ISO 日期字符串
 * @param format - 格式化模板，默认为 'YYYY-MM-DD'
 * @returns 格式化后的日期字符串
 */
export function formatDate(dateString: string, format: 'YYYY-MM-DD' | 'YYYY年MM月DD日' | 'MM/DD/YYYY' = 'YYYY-MM-DD'): string {
  const date = new Date(dateString);

  if (isNaN(date.getTime())) {
    return '';
  }

  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();

  switch (format) {
    case 'YYYY年MM月DD日':
      return `${year}年${String(month).padStart(2, '0')}月${String(day).padStart(2, '0')}日`;
    case 'MM/DD/YYYY':
      return `${String(month).padStart(2, '0')}/${String(day).padStart(2, '0')}/${year}`;
    case 'YYYY-MM-DD':
    default:
      return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
  }
}

/**
 * 文本截取函数（按字符数）
 * @param text - 原始文本
 * @param maxLength - 最大字符数
 * @param suffix - 截取后添加的后缀，默认为 '...'
 * @returns 截取后的文本
 */
export function truncateText(text: string, maxLength: number, suffix: string = '...'): string {
  if (!text) return '';
  if (text.length <= maxLength) return text;
  return text.slice(0, maxLength - suffix.length) + suffix;
}

/**
 * 文本截取函数（按单词数，适用于英文）
 * @param text - 原始文本
 * @param maxWords - 最大单词数
 * @param suffix - 截取后添加的后缀，默认为 '...'
 * @returns 截取后的文本
 */
export function truncateWords(text: string, maxWords: number, suffix: string = '...'): string {
  if (!text) return '';
  const words = text.split(/\s+/);
  if (words.length <= maxWords) return text;
  return words.slice(0, maxWords).join(' ') + suffix;
}

/**
 * 生成随机ID
 * @param prefix - ID 前缀，默认为 'id'
 * @returns 生成的随机 ID
 */
export function generateId(prefix: string = 'id'): string {
  return `${prefix}-${Math.random().toString(36).substring(2, 11)}`;
}

/**
 * 延迟函数
 * @param ms - 延迟毫秒数
 * @returns Promise
 */
export function delay(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

/**
 * 滚动到指定元素
 * @param elementId - 元素 ID
 * @param offset - 偏移量（像素）
 */
export function scrollToElement(elementId: string, offset: number = 80): void {
  const element = document.getElementById(elementId);
  if (element) {
    const elementPosition = element.getBoundingClientRect().top;
    const offsetPosition = elementPosition + window.pageYOffset - offset;

    window.scrollTo({
      top: offsetPosition,
      behavior: 'smooth',
    });
  }
}

/**
 * 检查是否在客户端环境
 * @returns 是否在浏览器环境中
 */
export function isClient(): boolean {
  return typeof window !== 'undefined';
}

/**
 * 获取 URL 查询参数
 * @param name - 参数名
 * @returns 参数值或 null
 */
export function getQueryParam(name: string): string | null {
  if (!isClient()) return null;
  const urlParams = new URLSearchParams(window.location.search);
  return urlParams.get(name);
}

/**
 * 数字格式化函数
 * @param num - 数字
 * @param locale - 地区设置，默认为 'zh-CN'
 * @returns 格式化后的字符串
 */
export function formatNumber(num: number, locale: string = 'zh-CN'): string {
  return new Intl.NumberFormat(locale).format(num);
}

/**
 * 字节单位转换
 * @param bytes - 字节数
 * @param decimals - 小数位数，默认为 2
 * @returns 格式化后的字符串
 */
export function formatBytes(bytes: number, decimals: number = 2): string {
  if (bytes === 0) return '0 Bytes';

  const k = 1024;
  const dm = decimals < 0 ? 0 : decimals;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

  const i = Math.floor(Math.log(bytes) / Math.log(k));

  return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

/**
 * 驼峰命名转短横线命名
 * @param str - 驼峰命名字符串
 * @returns 短横线命名字符串
 */
export function camelToKebab(str: string): string {
  return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}

/**
 * 短横线命名转驼峰命名
 * @param str - 短横线命名字符串
 * @returns 驼峰命名字符串
 */
export function kebabToCamel(str: string): string {
  return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
}

/**
 * 首字母大写
 * @param str - 输入字符串
 * @returns 首字母大写后的字符串
 */
export function capitalizeFirst(str: string): string {
  if (!str) return '';
  return str.charAt(0).toUpperCase() + str.slice(1);
}

/**
 * 移除字符串中的 HTML 标签
 * @param html - 包含 HTML 标签的字符串
 * @returns 纯文本字符串
 */
export function stripHtml(html: string): string {
  if (!html) return '';
  return html.replace(/<[^>]*>/g, '');
}

/**
 * 生成页面 SEO 元数据
 * @param title - 页面标题
 * @param description - 页面描述
 * @param keywords - 关键词
 * @returns 元数据对象数组
 */
export function generateSeoMeta(
  title: string,
  description: string,
  keywords: string[] = []
): Array<{ title: string; name: string; content: string }> {
  return [
    { title, name: '', content: title },
    { title: '', name: 'description', content: description },
    { title: '', name: 'keywords', content: keywords.join(', ') },
  ];
}

/**
 * 检查对象是否为空
 * @param obj - 要检查的对象
 * @returns 是否为空
 */
export function isEmpty(obj: object): boolean {
  if (obj === null || obj === undefined) return true;
  if (Array.isArray(obj)) return obj.length === 0;
  if (typeof obj === 'object') return Object.keys(obj).length === 0;
  return false;
}

/**
 * 深度合并对象
 * @param target - 目标对象
 * @param sources - 源对象数组
 * @returns 合并后的对象
 */
const isPlainObject = (value: unknown): value is Record<string, unknown> => {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
};

export function deepMerge<T extends Record<string, unknown>>(
  target: T,
  ...sources: Array<Partial<T>>
): T {
  if (!sources.length) return target;

  const source = sources.shift();
  if (!source) return target;

  for (const key of Object.keys(source) as Array<keyof T>) {
    const sourceValue = source[key];
    const targetValue = target[key];

    if (isPlainObject(sourceValue)) {
      if (!isPlainObject(targetValue)) {
        (target as Record<string, unknown>)[key as string] = {};
      }
      deepMerge(
        (target as Record<string, unknown>)[key as string] as Record<string, unknown>,
        sourceValue
      );
      continue;
    }

    (target as Record<string, unknown>)[key as string] = sourceValue as unknown;
  }

  return deepMerge(target, ...sources);
}

/**
 * 防抖函数
 * @param func - 要防抖的函数
 * @param wait - 等待时间（毫秒）
 * @returns 防抖后的函数
 */
export function debounce<T extends (...args: unknown[]) => unknown>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: ReturnType<typeof setTimeout> | null = null;

  return (...args: Parameters<T>) => {
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

/**
 * 节流函数
 * @param func - 要节流的函数
 * @param limit - 时间限制（毫秒）
 * @returns 节流后的函数
 */
export function throttle<T extends (...args: unknown[]) => unknown>(
  func: T,
  limit: number
): (...args: Parameters<T>) => void {
  let inThrottle = false;

  return (...args: Parameters<T>) => {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => (inThrottle = false), limit);
    }
  };
}
