import { StorageAdapter } from './StorageAdapter.js'
import fs from 'fs/promises'
import path from 'path'
import { existsSync } from 'fs'

/**
 * 本地文件系统适配器
 * 
 * 适用场景：
 * - 本地开发环境
 * - 私有化部署（数据不出内网）
 * - 单机版（100%本地化）
 * 
 * 存储结构：
 * - 基础路径：backend/uploads/
 * - 示例：backend/uploads/literature/123.pdf
 * 
 * @example
 * ```typescript
 * const adapter = new LocalAdapter('/app/uploads')
 * await adapter.upload('literature/123.pdf', buffer)
 * ```
 */
export class LocalAdapter implements StorageAdapter {
  private readonly baseDir: string
  private readonly baseUrl: string

  /**
   * @param baseDir 本地存储基础目录（绝对路径或相对路径）
   * @param baseUrl 访问URL前缀（默认：http://localhost:3001/uploads）
   */
  constructor(
    baseDir: string = path.join(process.cwd(), 'uploads'),
    baseUrl: string = process.env.LOCAL_STORAGE_URL || 'http://localhost:3001/uploads'
  ) {
    this.baseDir = baseDir
    this.baseUrl = baseUrl.replace(/\/$/, '') // 移除末尾的斜杠

    // 确保基础目录存在
    this.ensureBaseDir()
  }

  /**
   * 确保基础目录存在
   */
  private async ensureBaseDir(): Promise<void> {
    try {
      await fs.mkdir(this.baseDir, { recursive: true })
    } catch (error) {
      console.error(`[LocalAdapter] Failed to create base dir: ${this.baseDir}`, error)
      throw error
    }
  }

  /**
   * 确保文件所在目录存在
   */
  private async ensureDir(filePath: string): Promise<void> {
    const dir = path.dirname(filePath)
    await fs.mkdir(dir, { recursive: true })
  }

  /**
   * 获取完整的文件路径
   */
  private getFullPath(key: string): string {
    // 规范化路径，移除开头的斜杠
    const normalizedKey = key.replace(/^\/+/, '')
    return path.join(this.baseDir, normalizedKey)
  }

  /**
   * 上传文件
   */
  async upload(key: string, buffer: Buffer): Promise<string> {
    try {
      const fullPath = this.getFullPath(key)
      
      // 确保目录存在
      await this.ensureDir(fullPath)
      
      // 写入文件
      await fs.writeFile(fullPath, buffer)
      
      // 返回访问URL
      return this.getUrl(key)
    } catch (error) {
      console.error(`[LocalAdapter] Failed to upload file: ${key}`, error)
      throw new Error(`Failed to upload file: ${key}`)
    }
  }

  /**
   * 下载文件
   */
  async download(key: string): Promise<Buffer> {
    try {
      const fullPath = this.getFullPath(key)
      
      // 检查文件是否存在
      if (!existsSync(fullPath)) {
        throw new Error(`File not found: ${key}`)
      }
      
      // 读取文件
      return await fs.readFile(fullPath)
    } catch (error) {
      console.error(`[LocalAdapter] Failed to download file: ${key}`, error)
      throw new Error(`Failed to download file: ${key}`)
    }
  }

  /**
   * 删除文件
   */
  async delete(key: string): Promise<void> {
    try {
      const fullPath = this.getFullPath(key)
      
      // 检查文件是否存在
      if (existsSync(fullPath)) {
        await fs.unlink(fullPath)
      }
    } catch (error) {
      console.error(`[LocalAdapter] Failed to delete file: ${key}`, error)
      throw new Error(`Failed to delete file: ${key}`)
    }
  }

  /**
   * 获取文件访问URL
   */
  getUrl(key: string): string {
    // 规范化路径，确保开头有斜杠
    const normalizedKey = key.replace(/^\/+/, '')
    return `${this.baseUrl}/${normalizedKey}`
  }

  /**
   * 检查文件是否存在
   */
  async exists(key: string): Promise<boolean> {
    try {
      const fullPath = this.getFullPath(key)
      return existsSync(fullPath)
    } catch (error) {
      return false
    }
  }
}

