import { computed, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { fetchQuickEntryKeys, saveQuickEntryKeys } from '@/api/dashboardQuickEntries'
import {
  defaultQuickKeys, finalizeQuickKeys, getQuickEntryCatalog, isMandatoryQuickKey,
  MAX_QUICK_ENTRIES, normalizeQuickKeys, resolveQuickEntry, type QuickEntryDef
} from '@/config/quickEntries'
import { useAuthStore } from '@/stores/auth'
import type { Scope } from '@/types/auth'

export function useDashboardQuickEntries() {
  const auth = useAuthStore()
  const keys = ref<string[]>([])
  const loading = ref(false)
  const usingDefaults = ref(true)
  const pickerOpen = ref(false)

  const scope = computed(() => auth.scope ?? 'Platform')
  const userId = computed(() => auth.user?.id ?? '')

  /** 空列表仅在「尚未自定义」(usingDefaults) 时回退系统默认；用户主动清空则保持为空 */
  function effectiveKeys(): string[] {
    const base = keys.value.length > 0
      ? keys.value
      : (usingDefaults.value ? defaultQuickKeys(scope.value as Scope) : [])
    return finalizeQuickKeys(base, scope.value as Scope)
  }

  function filterByPermission(list: string[]): string[] {
    return list.filter((key) => {
      const def = resolveQuickEntry(key, scope.value as Scope)
      return def && auth.hasPage(def.pageKey)
    })
  }

  const resolvedEntries = computed<QuickEntryDef[]>(() => {
    return filterByPermission(effectiveKeys())
      .slice(0, MAX_QUICK_ENTRIES)
      .map((k) => resolveQuickEntry(k, scope.value as Scope))
      .filter((d): d is QuickEntryDef => !!d)
  })

  const pinnedKeys = computed(() => filterByPermission(effectiveKeys()))

  /** 弹窗展示全部可访问菜单（含已固定项，已固定项在弹窗内置灰不可选） */
  const pickerCatalog = computed(() =>
    getQuickEntryCatalog(scope.value as Scope).filter((item) => auth.hasPage(item.pageKey))
  )

  const canAddMore = computed(() => pinnedKeys.value.length < MAX_QUICK_ENTRIES)

  const availableToAdd = computed(() => {
    const current = new Set(pinnedKeys.value)
    return pickerCatalog.value.filter((item) => !current.has(item.key))
  })

  async function load() {
    if (!userId.value) {
      keys.value = defaultQuickKeys(scope.value as Scope)
      usingDefaults.value = true
      return
    }
    loading.value = true
    try {
      const dto = await fetchQuickEntryKeys(userId.value, scope.value)
      const loaded = normalizeQuickKeys(dto.keys)
      keys.value = loaded.length > 0
        ? finalizeQuickKeys(loaded, scope.value as Scope)
        : (dto.usingDefaults ? defaultQuickKeys(scope.value as Scope) : finalizeQuickKeys([], scope.value as Scope))
      usingDefaults.value = dto.usingDefaults
    } catch (e) {
      keys.value = defaultQuickKeys(scope.value as Scope)
      usingDefaults.value = true
      ElMessage.warning(`加载快捷入口失败：${e instanceof Error ? e.message : String(e)}`)
    } finally {
      loading.value = false
    }
  }

  async function persist(nextKeys: string[]) {
    const finalized = finalizeQuickKeys(nextKeys, scope.value as Scope)
    if (!userId.value) {
      keys.value = finalized
      return
    }
    try {
      const dto = await saveQuickEntryKeys(userId.value, scope.value, finalized)
      keys.value = finalizeQuickKeys(normalizeQuickKeys(dto.keys), scope.value as Scope)
      usingDefaults.value = dto.usingDefaults
    } catch (e) {
      ElMessage.error(`保存快捷入口失败：${e instanceof Error ? e.message : String(e)}`)
      throw e
    }
  }

  async function addKey(key: string) {
    const base = [...effectiveKeys()]
    if (base.includes(key)) {
      ElMessage.info('该菜单已在快捷入口中')
      return
    }
    if (base.length >= MAX_QUICK_ENTRIES) {
      ElMessage.warning(`快捷入口最多 ${MAX_QUICK_ENTRIES} 个`)
      return
    }
    await persist([...base, key])
    ElMessage.success('已添加快捷入口')
  }

  async function removeKey(key: string) {
    if (isMandatoryQuickKey(key, scope.value as Scope)) {
      ElMessage.warning('该快捷入口为系统默认项，不可移除')
      return
    }
    const base = [...effectiveKeys()]
    await persist(base.filter((k) => k !== key))
    ElMessage.success('已移除快捷入口')
  }

  async function swapKeys(keyA: string, keyB: string) {
    if (keyA === keyB || keyA === 'add' || keyB === 'add') return
    const list = [...pinnedKeys.value]
    const i = list.indexOf(keyA)
    const j = list.indexOf(keyB)
    if (i < 0 || j < 0 || i === j) return
    ;[list[i], list[j]] = [list[j], list[i]]
    await persist(list)
  }

  function openPicker() {
    pickerOpen.value = true
  }

  watch([userId, scope], () => { void load() }, { immediate: true })

  return {
    keys,
    loading,
    usingDefaults,
    pickerOpen,
    resolvedEntries,
    pickerCatalog,
    pinnedKeys,
    availableToAdd,
    canAddMore,
    load,
    addKey,
    removeKey,
    swapKeys,
    openPicker,
    isMandatoryQuickKey: (key: string) => isMandatoryQuickKey(key, scope.value as Scope)
  }
}
