import { computed, ref } from 'vue'
import { http } from '@/api'
import { normalizeRemotePath } from '@/utils/remotePath'

export type FilesClipboardMode = 'copy' | 'cut'

export interface FilesClipboardState {
  mode: FilesClipboardMode
  serverId: number
  paths: string[]
  label: string
}

const clipboard = ref<FilesClipboardState | null>(null)

export function useFilesClipboard() {
  const hasClipboard = computed(() => clipboard.value !== null)
  const clipboardSummary = computed(() => {
    if (!clipboard.value) return ''
    const verb = clipboard.value.mode === 'cut' ? '已剪切' : '已复制'
    return `${verb} ${clipboard.value.paths.length} 项`
  })

  function setFromSelection(
    mode: FilesClipboardMode,
    serverId: number,
    paths: string[],
  ) {
    if (!paths.length) return false
    const normalized = [...new Set(paths.map((p) => normalizeRemotePath(p)))]
    clipboard.value = {
      mode,
      serverId,
      paths: normalized,
      label: normalized.map((p) => p.split('/').pop() || p).join(', '),
    }
    return true
  }

  function clear() {
    clipboard.value = null
  }

  function canPasteOnServer(serverId: number | null): boolean {
    return Boolean(clipboard.value && serverId && clipboard.value.serverId === serverId)
  }

  /** 粘贴前校验（与后端 remote_path_validation 一致，含跨目录到父级） */
  function validatePasteTarget(sources: string[], destDir: string): string | null {
    const dest = normalizeRemotePath(destDir)
    for (const raw of sources) {
      const src = normalizeRemotePath(raw)
      if (dest === src) {
        return `「${src.split('/').pop() || src}」与目标路径相同，无需粘贴`
      }
      if (dest.startsWith(`${src}/`)) {
        return `不能粘贴到源目录「${src}」的内部`
      }
    }
    return null
  }

  async function pasteToDirectory(destDir: string): Promise<void> {
    const clip = clipboard.value
    if (!clip) throw new Error('剪贴板为空')
    const dest = normalizeRemotePath(destDir)
    const conflict = validatePasteTarget(clip.paths, dest)
    if (conflict) throw new Error(conflict)
    const mode = clip.mode === 'cut' ? 'move' : 'copy'
    await http.post('/sync/file-clipboard', {
      server_id: clip.serverId,
      mode,
      sources: clip.paths,
      dest_dir: dest,
    })
    if (clip.mode === 'cut') {
      clear()
    }
  }

  return {
    clipboard,
    hasClipboard,
    clipboardSummary,
    setFromSelection,
    clear,
    canPasteOnServer,
    validatePasteTarget,
    pasteToDirectory,
  }
}
