/**
 * OSS Transport — 通过 Wails IPC 调用 Go 后端 OSS 客户端
 */

import type {
  FsTransport, FileItem, FileOperationResult, DetectTypeResult,
} from './transport'
import type { ConnectionProfile } from './connection-manager'
import {
  OssConnect, OssDisconnect, OssListDir, OssReadFile,
  OssWriteFile, OssGetFileInfo, OssCreateDir, OssCreateFile,
  OssDeletePath, OssRenamePath, OssDownloadToTemp, OssGetCommonPaths,
  OssWriteBase64File, OssGetSignedURL,
} from '@bindings/u-desk/app'

function transformFile(file: any): FileItem {
  return { ...file, is_dir: file.is_dir, mod_time: file.mod_time }
}

function transformFileList(files: any[]): FileItem[] {
  return files.map(transformFile)
}

const PREVIEW_CACHE_MAX = 50

export class OssTransport implements FsTransport {
  private profile: ConnectionProfile
  private connID: string | null = null
  private previewCache = new Map<string, string>()
  private previewOrder: string[] = []

  constructor(profile: ConnectionProfile) {
    this.profile = profile
  }

  async connect(): Promise<string> {
    const result = await OssConnect({
      provider: this.profile.type,
      access_key: this.profile.accessKey || '',
      secret_key: this.profile.secretKey || '',
      endpoint: this.profile.endpoint || '',
    })
    this.connID = result
    return result
  }

  get sessionId(): string | null { return this.connID }

  async disconnect(): Promise<void> {
    if (this.connID) {
      try { await OssDisconnect(this.connID) } catch (e) {
        console.warn('[OSS] disconnect error:', e)
      }
      this.connID = null
    }
    this.previewCache.clear()
    this.previewOrder = []
  }

  private requireConn(): string {
    if (!this.connID) throw new Error('OSS 未连接')
    return this.connID
  }

  // ====== 文件列表与信息 ======

  async listDir(path: string): Promise<FileItem[]> {
    return transformFileList(await OssListDir(this.requireConn(), path))
  }

  async getFileInfo(path: string): Promise<Record<string, any>> {
    return OssGetFileInfo(this.requireConn(), path)
  }

  // ====== 文件读写 ======

  async readFile(path: string): Promise<string> {
    return OssReadFile(this.requireConn(), path)
  }

  async writeFile(path: string, content: string): Promise<void> {
    await OssWriteFile(this.requireConn(), path, content)
  }

  async saveBase64File(path: string, content: string): Promise<void> {
    if (!content) throw new Error('无效的 base64 内容')
    await OssWriteBase64File(this.requireConn(), path, content)
  }

  // ====== 文件操作 ======

  async createFile(dirPath: string, filename: string): Promise<FileOperationResult> {
    const fullPath = dirPath.replace(/\/$/, '') + '/' + filename
    return OssCreateFile(this.requireConn(), fullPath)
  }

  async createDir(parentPath: string, dirname: string): Promise<FileOperationResult> {
    const fullPath = parentPath.replace(/\/$/, '') + '/' + dirname
    return OssCreateDir(this.requireConn(), fullPath)
  }

  async deletePath(path: string): Promise<FileOperationResult> {
    return OssDeletePath(this.requireConn(), path)
  }

  async renamePath(oldPath: string, newPath: string): Promise<FileOperationResult> {
    return OssRenamePath({
      conn_id: this.requireConn(),
      old_path: oldPath,
      new_path: newPath,
    })
  }

  // ====== ZIP 操作（不支持）======

  async listZipContents(_zipPath: string): Promise<FileItem[]> {
    throw new Error('ZIP 操作在 OSS 模式暂未实现')
  }

  async extractFileFromZip(_zipPath: string, _filePath: string): Promise<string> {
    throw new Error('ZIP 操作在 OSS 模式暂未实现')
  }

  async extractFileFromZipToTemp(_zipPath: string, _filePath: string): Promise<string> {
    throw new Error('ZIP 操作在 OSS 模式暂未实现')
  }

  async getZipFileInfo(_zipPath: string, _filePath: string): Promise<FileItem> {
    throw new Error('ZIP 操作在 OSS 模式暂未实现')
  }

  // ====== 系统操作 ======

  async openPath(_path: string): Promise<void> {
    throw new Error('OSS 模式不支持打开本地路径')
  }

  async getFileServerURL(): Promise<string> {
    return ''
  }

  getPreviewToken(): string {
    return ''
  }

  async resolveShortcut(_lnkPath: string): Promise<any> {
    return null
  }

  async detectFileTypeByContent(_path: string): Promise<DetectTypeResult> {
    return { extension: '', category: 'unknown', mime_type: '', confidence: 0 }
  }

  async getCommonPaths(): Promise<Record<string, string>> {
    return OssGetCommonPaths(this.requireConn())
  }

  // ====== 回收站（无）======

  async getRecycleBinEntries(): Promise<any[]> {
    return []
  }

  async restoreFromRecycleBin(_path: string): Promise<void> {}

  async deletePermanently(_path: string): Promise<void> {}

  async emptyRecycleBin(): Promise<void> {}

  // ====== 预览辅助 ======

  async downloadForPreview(remotePath: string): Promise<string> {
    if (this.previewCache.has(remotePath)) {
      this.previewOrder = this.previewOrder.filter(p => p !== remotePath)
      this.previewOrder.push(remotePath)
      return this.previewCache.get(remotePath)!
    }
    const localPath = await OssDownloadToTemp(this.requireConn(), remotePath)

    if (this.previewOrder.length >= PREVIEW_CACHE_MAX) {
      const oldest = this.previewOrder.shift()!
      this.previewCache.delete(oldest)
    }

    this.previewCache.set(remotePath, localPath)
    this.previewOrder.push(remotePath)
    return localPath
  }

  /** 获取预签名 URL（用于直接预览） */
  async getSignedUrl(key: string): Promise<string> {
    return OssGetSignedURL(this.requireConn(), key)
  }
}
