/**
 * Http Transport — 远程文件操作（通过 u-fs-agent REST API）
 */

import type { FsTransport, FileItem, FileOperationResult, DetectTypeResult } from './transport'

const CONTENT_TYPE = 'application/json'

export class HttpTransport implements FsTransport {
  private baseUrl: string
  private token: string

  constructor(host: string, port: number, token: string) {
    const scheme = port === 443 ? 'https' : 'http'
    this.baseUrl = `${scheme}://${host}${port === 80 || port === 443 ? '' : ':' + port}`
    this.token = token
  }

  private headers(): HeadersInit {
    const h: Record<string, string> = { 'Content-Type': CONTENT_TYPE }
    if (this.token) h['Authorization'] = `Bearer ${this.token}`
    return h
  }

  private async request<T>(method: string, path: string, params?: Record<string, string>, body?: any): Promise<T> {
    const url = `${this.baseUrl}${path}`
    const searchParams = params ? '?' + new URLSearchParams(params).toString() : ''
    const opts: RequestInit = {
      method,
      headers: this.headers(),
    }
    if (body !== undefined) opts.body = JSON.stringify(body)

    const res = await fetch(url + searchParams, opts)
    if (!res.ok) {
      const text = await res.text().catch(() => '')
      throw new Error(`HTTP ${res.status}: ${text.slice(0, 200)}`)
    }
    const data = await res.json()

    if (data.code >= 400) {
      throw new Error(data.message || `请求失败 (code=${data.code})`)
    }
    return data.data ?? data
  }

  async listDir(path: string): Promise<FileItem[]> {
    return this.request<FileItem[]>('GET', '/api/v1/fs', { path })
  }

  async getFileInfo(path: string): Promise<Record<string, any>> {
    return this.request<Record<string, any>>('GET', '/api/v1/fs', { path, get: 'stat' })
  }

  async readFile(path: string): Promise<string> {
    const data = await this.request<{ content: string }>('GET', '/api/v1/fs/read', { path })
    return data.content
  }

  async writeFile(path: string, content: string): Promise<void> {
    await this.request('PUT', '/api/v1/fs/write', { path }, { content })
  }

  async saveBase64File(path: string, content: string): Promise<void> {
    if (!content) throw new Error('无效的 base64 内容')
    await this.request('POST', '/api/v1/fs/upload', { path }, { content })
  }

  async createFile(dirPath: string, filename: string): Promise<FileOperationResult> {
    return this.request<FileOperationResult>('POST', '/api/v1/fs/create', { path: dirPath }, { type: 'file', name: filename })
  }

  async createDir(parentPath: string, dirname: string): Promise<FileOperationResult> {
    return this.request<FileOperationResult>('POST', '/api/v1/fs/create', { path: parentPath }, { type: 'dir', name: dirname })
  }

  async deletePath(path: string): Promise<FileOperationResult> {
    return this.request<FileOperationResult>('DELETE', '/api/v1/fs/delete', { path })
  }

  async renamePath(oldPath: string, newPath: string): Promise<FileOperationResult> {
    return this.request<FileOperationResult>('PATCH', '/api/v1/fs/rename', { path: oldPath }, { new_path: newPath })
  }

  async listZipContents(zipPath: string): Promise<FileItem[]> {
    // Wave 3 实现
    throw new Error('ZIP 操作在远程模式暂未实现')
  }

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

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

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

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

  async getFileServerURL(): Promise<string> {
    return `${this.baseUrl}/api/v1/proxy/localfs`
  }

  /** 远程模式预览用的认证 token（拼接到 URL query） */
  getPreviewToken(): string {
    return this.token
  }

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

  async detectFileTypeByContent(path: string): Promise<DetectTypeResult> {
    return this.request<DetectTypeResult>('GET', '/api/v1/fs/detect', { path })
  }

  async getCommonPaths(): Promise<Record<string, string>> {
    return this.request<Record<string, string>>('GET', '/api/v1/system/common-paths')
  }

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

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

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

  async emptyRecycleBin(): Promise<void> {}
}
