import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import { http } from '@/api'
import { useSnackbar } from '@/composables/useSnackbar'
import { useFilesStore } from '@/stores/files'
import type { FilesCapabilityResult } from '@/types/api'
import {
  buildFilesAccessHint,
  isEntryLikelyUnreadable,
} from '@/utils/fileMode'
import { FILES_HINT_DISMISSED_KEY } from './constants'
import { isNotFoundError } from './useFilesBrowse'

export function useFilesPermissions(options: {
  browse: (opts?: { force?: boolean }) => Promise<void | undefined>
}) {
  const snackbar = useSnackbar()
  const store = useFilesStore()
  const {
    selectedServer,
    files,
    browseError,
    filesCapability,
    lastReadDeniedPath,
    accessHintDismissed,
    setupSudoLoading,
    setupSudoDone,
  } = storeToRefs(store)

  const sshUserForFiles = computed(() => filesCapability.value?.ssh_user ?? null)

  const unreadableFileCount = computed(() => {
    const user = sshUserForFiles.value
    if (!user) return 0
    return files.value.filter((f) => isEntryLikelyUnreadable(f, user)).length
  })

  const filesAccessHint = computed(() => {
    if (accessHintDismissed.value || !selectedServer.value) return null
    if (browseError.value && isNotFoundError(browseError.value)) return null
    const cap = filesCapability.value
    return buildFilesAccessHint({
      sshUser: cap?.ssh_user,
      canSudo: cap?.can_sudo_nopasswd ?? false,
      whitelistOk: cap?.whitelist_ok ?? false,
      isRootSsh: cap?.is_root ?? false,
      filesElevation: cap?.files_elevation,
      capabilityMessage: cap?.message,
      lastReadDeniedPath: lastReadDeniedPath.value,
      unreadableCount: unreadableFileCount.value,
    })
  })

  function dismissFilesAccessHint() {
    accessHintDismissed.value = true
    sessionStorage.setItem(FILES_HINT_DISMISSED_KEY, '1')
  }

  async function refreshFilesCapability() {
    if (!selectedServer.value) {
      filesCapability.value = null
      return
    }
    try {
      filesCapability.value = await http.get<FilesCapabilityResult>(
        `/servers/${selectedServer.value}/files-capability`,
      )
    } catch {
      filesCapability.value = null
    }
  }

  async function setupFilesSudo() {
    if (!selectedServer.value) return
    setupSudoLoading.value = true
    try {
      const res = await http.post<{ ok: boolean; message: string }>(
        `/servers/${selectedServer.value}/setup-files-sudo`,
        {},
      )
      setupSudoDone.value = true
      snackbar(res.message || 'sudoers 配置成功，文件管理器现在可自动提权', 'success')
      dismissFilesAccessHint()
      await refreshFilesCapability()
      await options.browse({ force: true })
    } catch (e: unknown) {
      const msg = e instanceof Error ? e.message : '配置失败'
      snackbar(`一键配置失败：${msg}`, 'error')
    } finally {
      setupSudoLoading.value = false
    }
  }

  return {
    sshUserForFiles,
    filesAccessHint,
    dismissFilesAccessHint,
    refreshFilesCapability,
    setupFilesSudo,
  }
}
