import { Injectable, Logger } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import * as fs from 'fs'
import * as path from 'path'
import * as crypto from 'crypto'
import { Platform } from '../../domain/version-management'

export interface FileUploadResult {
  url: string
  size: number
  sha256: string
  filename: string
}

@Injectable()
export class FileStorageService {
  private readonly logger = new Logger(FileStorageService.name)
  private readonly uploadDir: string
  private readonly baseUrl: string

  constructor(private readonly configService: ConfigService) {
    this.uploadDir = this.configService.get<string>('UPLOAD_DIR', './uploads')
    this.baseUrl = this.configService.get<string>('UPLOAD_BASE_URL', 'http://localhost:3023/downloads')

    // 确保上传目录存在
    this.ensureUploadDir()
  }

  private ensureUploadDir(): void {
    if (!fs.existsSync(this.uploadDir)) {
      fs.mkdirSync(this.uploadDir, { recursive: true })
      this.logger.log(`Created upload directory: ${this.uploadDir}`)
    }
  }

  async saveFile(
    buffer: Buffer,
    originalFilename: string,
    platform: Platform,
    versionName: string,
  ): Promise<FileUploadResult> {
    // 生成唯一文件名
    const ext = path.extname(originalFilename).toLowerCase()
    const timestamp = Date.now()
    const randomSuffix = crypto.randomBytes(4).toString('hex')
    const filename = `${platform.toLowerCase()}-${versionName}-${timestamp}-${randomSuffix}${ext}`
    const filepath = path.join(this.uploadDir, filename)

    // 计算 SHA-256
    const sha256 = crypto.createHash('sha256').update(buffer).digest('hex')

    // 保存文件
    await fs.promises.writeFile(filepath, buffer)
    this.logger.log(`Saved file: ${filepath} (${buffer.length} bytes, SHA256: ${sha256})`)

    return {
      url: `${this.baseUrl}/${filename}`,
      size: buffer.length,
      sha256,
      filename,
    }
  }

  async deleteFile(filename: string): Promise<void> {
    const filepath = path.join(this.uploadDir, filename)
    if (fs.existsSync(filepath)) {
      await fs.promises.unlink(filepath)
      this.logger.log(`Deleted file: ${filepath}`)
    }
  }

  getFilePath(filename: string): string {
    return path.join(this.uploadDir, filename)
  }
}
