/**
 * 根据支持的文件类型生成 accept 属性值
 *
 * @param supportedFileTypes 支持的文件类型数组，如 ['PDF', 'DOC', 'DOCX']
 * @returns 用于文件上传组件 accept 属性的字符串
 */
export function generateAcceptedFileTypes(
  supportedFileTypes: string[],
): string {
  const allowedExtensions = supportedFileTypes.map((ext) => ext.toLowerCase());
  const mimeTypes: string[] = [];

  // 添加常见的 MIME 类型映射
  if (allowedExtensions.includes('txt')) {
    mimeTypes.push('text/plain');
  }
  if (allowedExtensions.includes('pdf')) {
    mimeTypes.push('application/pdf');
  }
  if (allowedExtensions.includes('html') || allowedExtensions.includes('htm')) {
    mimeTypes.push('text/html');
  }
  if (allowedExtensions.includes('csv')) {
    mimeTypes.push('text/csv');
  }
  if (allowedExtensions.includes('xlsx') || allowedExtensions.includes('xls')) {
    mimeTypes.push(
      'application/vnd.ms-excel',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
  }
  if (allowedExtensions.includes('docx') || allowedExtensions.includes('doc')) {
    mimeTypes.push(
      'application/msword',
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    );
  }
  if (allowedExtensions.includes('pptx') || allowedExtensions.includes('ppt')) {
    mimeTypes.push(
      'application/vnd.ms-powerpoint',
      'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    );
  }
  if (allowedExtensions.includes('xml')) {
    mimeTypes.push('application/xml', 'text/xml');
  }
  if (
    allowedExtensions.includes('md') ||
    allowedExtensions.includes('markdown')
  ) {
    mimeTypes.push('text/markdown');
  }
  if (allowedExtensions.includes('epub')) {
    mimeTypes.push('application/epub+zip');
  }
  if (allowedExtensions.includes('eml')) {
    mimeTypes.push('message/rfc822');
  }
  if (allowedExtensions.includes('msg')) {
    mimeTypes.push('application/vnd.ms-outlook');
  }

  // 添加文件扩展名
  const extensions = allowedExtensions.map((ext) => `.${ext}`);

  return [...mimeTypes, ...extensions].join(',');
}

/**
 * 从 URL 中提取文件名
 *
 * @param url 文件 URL
 * @returns 文件名，如果无法提取则返回 'unknown'
 */
export function getFileNameFromUrl(url: null | string | undefined): string {
  // 处理空值
  if (!url) {
    return 'unknown';
  }

  try {
    const urlObj = new URL(url);
    const pathname = urlObj.pathname;
    const fileName = pathname.split('/').pop() || 'unknown';
    return decodeURIComponent(fileName);
  } catch {
    // 如果 URL 解析失败，尝试从字符串中提取
    const parts = url.split('/');
    return parts[parts.length - 1] || 'unknown';
  }
}

/**
 * 默认图片类型
 */
export const defaultImageAccepts = [
  'bmp',
  'gif',
  'jpeg',
  'jpg',
  'png',
  'svg',
  'webp',
];

/**
 * 图片类 MIME 子类型到扩展名的别名映射；未列出的子类型按字面量与扩展名比较
 */
const IMAGE_MIME_SUBTYPE_ALIASES: Record<string, string[]> = {
  apng: ['apng', 'png'],
  jpeg: ['jpeg', 'jpg'],
  pjpeg: ['jpeg', 'jpg'],
  'svg+xml': ['svg'],
  tiff: ['tif', 'tiff'],
  'x-icon': ['ico'],
};

/**
 * 判断 MIME 子类型是否与文件扩展名匹配；image/* 限定为已知图片扩展名集合
 */
function matchMimeSubtype(subtype: string, ext: string): boolean {
  if (subtype === '*') {
    return defaultImageAccepts.includes(ext);
  }
  const aliases = IMAGE_MIME_SUBTYPE_ALIASES[subtype];
  if (aliases) {
    return aliases.includes(ext);
  }
  return subtype === ext;
}

/**
 * 判断文件是否为图片
 *
 * @param filename 文件名
 * @param accepts 支持的文件类型，兼容 MIME（如 image/png）、.ext（如 .png）与纯后缀（如 png）
 * @returns 是否为图片
 */
export function isImage(
  filename: null | string | undefined,
  accepts: string[] = defaultImageAccepts,
): boolean {
  if (!filename || accepts.length === 0) {
    return false;
  }
  const ext = filename.split('.').pop()?.toLowerCase() || '';
  if (!ext) {
    return false;
  }
  return accepts.some((accept) => {
    const lower = accept.toLowerCase();
    // MIME 类型，例如 image/png ；image/* 仅放行已知图片扩展
    if (lower.includes('/')) {
      const subtype = lower.split('/').pop() || '';
      return matchMimeSubtype(subtype, ext);
    }
    // 以点号开头的扩展名，例如 .png
    if (lower.startsWith('.')) {
      return lower.slice(1) === ext;
    }
    // 纯后缀
    return lower === ext;
  });
}

/**
 * 判断文件是否为指定类型
 *
 * @param file 文件
 * @param accepts 支持的文件类型
 * @returns 是否为指定类型
 */
export function checkFileType(file: File, accepts: string[]) {
  if (!accepts || accepts.length === 0) {
    return true;
  }
  const newTypes = accepts.join('|');
  const reg = new RegExp(`${String.raw`\.(` + newTypes})$`, 'i');
  return reg.test(file.name);
}

/**
 * 格式化文件大小
 *
 * @param bytes 文件大小（字节）
 * @returns 格式化后的文件大小字符串
 */
export function formatFileSize(bytes: number, digits = 2): string {
  if (bytes === 0) {
    return '0 B';
  }
  const k = 1024;
  const unitArr = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
  const index = Math.floor(Math.log(bytes) / Math.log(k));
  return `${Number.parseFloat((bytes / k ** index).toFixed(digits))} ${unitArr[index]}`;
}

/**
 * 预览文件类型
 */
export type PreviewFileType =
  | 'docx'
  | 'excel'
  | 'image'
  | 'pdf'
  | 'pptx'
  | 'unknown';

/**
 * 根据文件名判断预览文件类型
 *
 * @param filename 文件名或 URL
 * @returns 预览文件类型
 */
export function getFileType(filename: null | string | undefined): PreviewFileType {
  if (!filename) return 'unknown';
  const ext = filename.split('.').pop()?.toLowerCase() || '';
  if (isImage(ext)) return 'image';
  if (ext === 'pdf') return 'pdf';
  if (['doc', 'docx'].includes(ext)) return 'docx';
  if (['xls', 'xlsx'].includes(ext)) return 'excel';
  if (['ppt', 'pptx'].includes(ext)) return 'pptx';
  return 'unknown';
}

/**
 * 获取文件图标（Lucide Icons）
 *
 * @param filename 文件名
 * @returns Lucide 图标名称
 */
export function getFileIcon(filename: null | string | undefined): string {
  if (!filename) {
    return 'lucide:file';
  }
  const ext = filename.split('.').pop()?.toLowerCase() || '';
  if (isImage(ext)) {
    return 'lucide:image';
  }
  if (['pdf'].includes(ext)) {
    return 'lucide:file-text';
  }
  if (['doc', 'docx'].includes(ext)) {
    return 'lucide:file-text';
  }
  if (['xls', 'xlsx'].includes(ext)) {
    return 'lucide:file-spreadsheet';
  }
  if (['ppt', 'pptx'].includes(ext)) {
    return 'lucide:presentation';
  }
  if (['aac', 'm4a', 'mp3', 'wav'].includes(ext)) {
    return 'lucide:music';
  }
  if (['avi', 'mov', 'mp4', 'wmv'].includes(ext)) {
    return 'lucide:video';
  }
  return 'lucide:file';
}

/**
 * 获取文件类型样式类（Tailwind CSS 渐变色）
 *
 * @param filename 文件名
 * @returns Tailwind CSS 渐变类名
 */
export function getFileTypeClass(filename: null | string | undefined): string {
  if (!filename) {
    return 'from-gray-500 to-gray-700';
  }
  const ext = filename.split('.').pop()?.toLowerCase() || '';
  if (isImage(ext)) {
    return 'from-yellow-400 to-orange-500';
  }
  if (['pdf'].includes(ext)) {
    return 'from-red-500 to-red-700';
  }
  if (['doc', 'docx'].includes(ext)) {
    return 'from-blue-600 to-blue-800';
  }
  if (['xls', 'xlsx'].includes(ext)) {
    return 'from-green-600 to-green-800';
  }
  if (['ppt', 'pptx'].includes(ext)) {
    return 'from-orange-600 to-orange-800';
  }
  if (['aac', 'm4a', 'mp3', 'wav'].includes(ext)) {
    return 'from-purple-500 to-purple-700';
  }
  if (['avi', 'mov', 'mp4', 'wmv'].includes(ext)) {
    return 'from-red-500 to-red-700';
  }
  return 'from-gray-500 to-gray-700';
}
