/**
 * 统一存储服务
 * 支持 OSS 和本地存储的无缝切换
 */

import { ossService } from './oss.service';
import path from 'path';
import fs from 'fs';
import { v4 as uuidv4 } from 'uuid';

export type StorageType = 'oss' | 'local';

class StorageService {
  private storageType: StorageType;

  constructor() {
    // 从环境变量读取存储类型，默认 local
    this.storageType = (process.env.STORAGE_TYPE as StorageType) || 'local';
    console.log(`[Storage] 当前存储模式: ${this.storageType}`);
  }

  /**
   * 切换存储类型
   */
  setStorageType(type: StorageType) {
    this.storageType = type;
    console.log(`[Storage] 存储模式已切换为: ${type}`);
  }

  /**
   * 获取当前存储类型
   */
  getStorageType(): StorageType {
    return this.storageType;
  }

  /**
   * 上传音频文件
   * @param localPath 本地文件路径
   * @param audioId 音频 ID
   * @returns 文件 URL
   */
  async uploadAudio(localPath: string, audioId: string): Promise<string> {
    if (this.storageType === 'oss') {
      return await ossService.uploadAudio(localPath, audioId);
    } else {
      return this.uploadToLocal(localPath, 'audio', audioId);
    }
  }

  /**
   * 上传视频文件
   * @param localPath 本地文件路径
   * @param videoId 视频 ID
   * @returns 文件 URL
   */
  async uploadVideo(localPath: string, videoId: string): Promise<string> {
    if (this.storageType === 'oss') {
      return await ossService.uploadVideo(localPath, videoId);
    } else {
      return this.uploadToLocal(localPath, 'video', videoId);
    }
  }

  /**
   * 上传封面图片
   * @param localPath 本地文件路径
   * @param bookId 书籍 ID
   * @returns 文件 URL
   */
  async uploadCover(localPath: string, bookId: string | number): Promise<string> {
    if (this.storageType === 'oss') {
      return await ossService.uploadCover(localPath, bookId);
    } else {
      return this.uploadToLocal(localPath, 'cover', String(bookId));
    }
  }

  /**
   * 上传通用文件
   * @param localPath 本地文件路径
   * @param category 分类（audio/video/cover/material）
   * @param id ID
   * @returns 文件 URL
   */
  async uploadFile(localPath: string, category: string, id: string): Promise<string> {
    if (this.storageType === 'oss') {
      const objectKey = `${category}/${id}/${path.basename(localPath)}`;
      return await ossService.uploadFile(localPath, objectKey);
    } else {
      return this.uploadToLocal(localPath, category, id);
    }
  }

  /**
   * 上传 Buffer
   * @param buffer 文件 Buffer
   * @param objectKey 对象键
   * @param contentType 内容类型
   * @returns 文件 URL
   */
  async uploadBuffer(buffer: Buffer, objectKey: string, contentType?: string): Promise<string> {
    if (this.storageType === 'oss') {
      return await ossService.uploadBuffer(buffer, objectKey, contentType);
    } else {
      // 本地存储：保存到 uploads 目录
      const filePath = path.join(process.cwd(), 'uploads', objectKey);
      const dir = path.dirname(filePath);
      
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
      }
      
      fs.writeFileSync(filePath, buffer);
      return `/uploads/${objectKey}`;
    }
  }

  /**
   * 删除文件
   * @param url 文件 URL 或路径
   */
  async deleteFile(url: string): Promise<void> {
    if (this.storageType === 'oss') {
      // 从 URL 提取 objectKey
      const objectKey = this.extractObjectKey(url);
      if (objectKey) {
        await ossService.deleteFile(objectKey);
      }
    } else {
      // 本地存储：删除文件
      const filePath = this.urlToLocalPath(url);
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
    }
  }

  /**
   * 删除整个目录
   * @param prefix 目录前缀或分类
   * @param id ID
   */
  async deleteDirectory(prefix: string, id: string): Promise<void> {
    if (this.storageType === 'oss') {
      await ossService.deleteDirectory(`${prefix}/${id}`);
    } else {
      const dirPath = path.join(process.cwd(), 'uploads', prefix, id);
      if (fs.existsSync(dirPath)) {
        fs.rmSync(dirPath, { recursive: true, force: true });
      }
    }
  }

  /**
   * 下载文件（用于音频下载功能）
   * @param url 文件 URL
   * @returns 文件 Buffer
   */
  async downloadFile(url: string): Promise<Buffer> {
    if (this.storageType === 'oss') {
      // OSS：从 OSS 下载
      const objectKey = this.extractObjectKey(url);
      if (!objectKey) {
        throw new Error('无效的 OSS URL');
      }
      return await ossService.downloadFile(objectKey);
    } else {
      // 本地存储：读取本地文件
      const filePath = this.urlToLocalPath(url);
      if (!fs.existsSync(filePath)) {
        throw new Error('文件不存在');
      }
      return fs.readFileSync(filePath);
    }
  }

  /**
   * 获取签名 URL（仅 OSS 支持）
   * @param url 文件 URL
   * @param expires 过期时间（秒）
   * @returns 签名 URL
   */
  async getSignedUrl(url: string, expires: number = 3600): Promise<string> {
    if (this.storageType === 'oss') {
      const objectKey = this.extractObjectKey(url);
      if (objectKey) {
        return await ossService.getSignedUrl(objectKey, expires);
      }
    }
    // 本地存储直接返回原 URL
    return url;
  }

  /**
   * 本地存储：上传文件
   */
  private uploadToLocal(localPath: string, category: string, id: string): string {
    const uploadDir = path.join(process.cwd(), 'uploads', category, id);
    
    // 确保目录存在
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }

    // 复制文件
    const filename = path.basename(localPath);
    const destPath = path.join(uploadDir, filename);
    fs.copyFileSync(localPath, destPath);

    // 返回访问 URL
    return `/uploads/${category}/${id}/${filename}`;
  }

  /**
   * 从 URL 提取 objectKey
   */
  private extractObjectKey(url: string): string | null {
    if (!url) return null;
    
    // OSS URL 格式: https://bucket.endpoint/objectKey
    if (url.includes('aliyuncs.com') || url.includes('oss-')) {
      try {
        const urlObj = new URL(url);
        return urlObj.pathname.substring(1); // 去掉开头的 /
      } catch {
        return null;
      }
    }
    
    // 本地 URL 格式: /uploads/category/id/filename
    if (url.startsWith('/uploads/')) {
      return url.substring('/uploads/'.length);
    }
    
    return null;
  }

  /**
   * URL 转本地路径
   */
  private urlToLocalPath(url: string): string {
    if (url.startsWith('/uploads/')) {
      return path.join(process.cwd(), 'uploads', url.substring('/uploads/'.length));
    }
    return url;
  }

  /**
   * 测试存储连接
   */
  async testConnection(): Promise<boolean> {
    if (this.storageType === 'oss') {
      return await ossService.testConnection();
    } else {
      // 测试本地存储
      const testDir = path.join(process.cwd(), 'uploads');
      try {
        if (!fs.existsSync(testDir)) {
          fs.mkdirSync(testDir, { recursive: true });
        }
        const testFile = path.join(testDir, '.test');
        fs.writeFileSync(testFile, 'test');
        fs.unlinkSync(testFile);
        console.log('[Storage] 本地存储测试成功');
        return true;
      } catch (error) {
        console.error('[Storage] 本地存储测试失败:', error);
        return false;
      }
    }
  }
}

// 导出单例
export const storageService = new StorageService();
export default storageService;
