/**
 * 多文件预览 Tab 管理 Composable
 * 管理预览 Tab 列表、激活状态、内容缓存、会话持久化
 */

import { ref, computed, watch } from 'vue'
import { STORAGE_KEYS } from '@/utils/constants'
import type { FileItem } from '@/types/file-system'

export interface PreviewTab {
  /** 唯一标识（基于路径） */
  id: string
  /** 文件信息 */
  fileItem: FileItem
  /** 缓存的预览 URL */
  previewUrl: string
  /** 缓存的文件内容 */
  fileContent: string
  /** 缓存的原始内容 */
  originalContent: string
  /** 缓存的编辑模式状态 */
  isEditMode: boolean
  /** 缓存的渲染内容 (HTML/Markdown) */
  rendered: string
  /** 是否已加载过内容 */
  loaded: boolean
}

/** 持久化存储的精简结构 */
interface PersistedTab {
  path: string
  active: boolean
  /** 未保存的内容（有修改时才存） */
  unsavedContent?: string
  originalContent?: string
  isEditMode?: boolean
}

const MAX_TABS = 10
const STORAGE_KEY = STORAGE_KEYS.FILESYSTEM.MULTI_PREVIEW_TABS

interface UnsavedEntry {
  content: string
  original: string
  editMode: boolean
}

interface RestoredSession {
  paths: string[]
  activePath: string | null
  unsavedMap: Map<string, UnsavedEntry>
}

function pathToId(path: string): string {
  return path.replace(/\\/g, '/').toLowerCase()
}

export function isDirty(tab: PreviewTab): boolean {
  return !!(tab.fileContent && tab.originalContent !== undefined && tab.fileContent !== tab.originalContent)
}

export function useMultiPreview() {
  const tabs = ref<PreviewTab[]>([])
  const activeTabId = ref<string | null>(null)

  const activeTab = computed<PreviewTab | null>(() => {
    if (!activeTabId.value) return null
    return tabs.value.find(t => t.id === activeTabId.value) || null
  })

  /** 创建一个新 tab */
  const createTab = (fileItem: FileItem): PreviewTab => ({
    id: pathToId(fileItem.path),
    fileItem,
    previewUrl: '',
    fileContent: '',
    originalContent: '',
    isEditMode: false,
    rendered: '',
    loaded: false
  })

  // ========== 持久化 ==========

  /** 从 localStorage 恢复会话 */
  const restoreSession = (): RestoredSession => {
    const unsavedMap = new Map<string, UnsavedEntry>()
    let activePath: string | null = null
    const paths: string[] = []

    try {
      const raw = localStorage.getItem(STORAGE_KEY)
      if (!raw) return { paths, activePath, unsavedMap }

      const persisted: PersistedTab[] = JSON.parse(raw)
      if (!Array.isArray(persisted)) return { paths, activePath, unsavedMap }

      for (const p of persisted) {
        if (!p.path) continue
        paths.push(p.path)
        if (p.active) activePath = p.path
        if (p.unsavedContent !== undefined) {
          unsavedMap.set(pathToId(p.path), {
            content: p.unsavedContent,
            original: p.originalContent || '',
            editMode: p.isEditMode || false
          })
        }
      }
    } catch {
      localStorage.removeItem(STORAGE_KEY)
    }

    return { paths, activePath, unsavedMap }
  }

  /** 保存会话到 localStorage */
  const persistSession = () => {
    const persisted: PersistedTab[] = tabs.value.map(tab => {
      const hasUnsaved = tab.fileContent && tab.originalContent !== undefined && tab.fileContent !== tab.originalContent
      // 限制存储大小，超过 100KB 的内容不存入 localStorage
      const canSave = hasUnsaved && tab.fileContent.length <= 100_000
      return {
        path: tab.fileItem.path,
        active: tab.id === activeTabId.value,
        unsavedContent: canSave ? tab.fileContent : undefined,
        originalContent: canSave ? tab.originalContent : undefined,
        isEditMode: canSave ? tab.isEditMode : undefined
      }
    })

    try {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(persisted))
    } catch {
      // localStorage 满了，忽略
    }
  }

  /** 恢复未保存内容到 tab */
  const applyUnsavedContent = (tab: PreviewTab, unsavedMap: Map<string, UnsavedEntry>) => {
    const unsaved = unsavedMap.get(tab.id)
    if (unsaved) {
      tab.fileContent = unsaved.content
      tab.originalContent = unsaved.original
      tab.isEditMode = unsaved.editMode
      tab.loaded = true // 标记为已加载，避免重新从磁盘读取覆盖
    }
  }

  /** 添加或激活 tab，返回 { tab, isNew } */
  const addTab = (fileItem: FileItem): { tab: PreviewTab; isNew: boolean } => {
    const id = pathToId(fileItem.path)
    const existing = tabs.value.find(t => t.id === id)
    if (existing) {
      activeTabId.value = id
      return { tab: existing, isNew: false }
    }

    // 超出上限，移除非活跃的最早 tab
    if (tabs.value.length >= MAX_TABS) {
      const victimIdx = tabs.value.findIndex(t => t.id !== activeTabId.value && t.id !== id)
      if (victimIdx !== -1) tabs.value.splice(victimIdx, 1)
    }

    const tab = createTab(fileItem)
    tabs.value.push(tab)
    activeTabId.value = tab.id
    return { tab, isNew: true }
  }

  /** 切换 tab */
  const switchTab = (tabId: string) => {
    if (tabs.value.find(t => t.id === tabId)) {
      activeTabId.value = tabId
    }
  }

  /** 关闭 tab，返回关闭后应激活的 tabId */
  const removeTab = (tabId: string): string | null => {
    const idx = tabs.value.findIndex(t => t.id === tabId)
    if (idx === -1) return activeTabId.value

    tabs.value.splice(idx, 1)

    if (activeTabId.value === tabId) {
      const nextIdx = Math.min(idx, tabs.value.length - 1)
      const nextTab = tabs.value[nextIdx] || null
      activeTabId.value = nextTab?.id || null
    }

    return activeTabId.value
  }

  /** 缓存当前 tab 的状态（切换前调用） */
  const cacheCurrentTab = (state: {
    previewUrl: string
    fileContent: string
    originalContent: string
    isEditMode: boolean
    rendered: string
  }) => {
    if (!activeTabId.value) return
    const tab = tabs.value.find(t => t.id === activeTabId.value)
    if (tab) {
      tab.previewUrl = state.previewUrl
      tab.fileContent = state.fileContent
      tab.originalContent = state.originalContent
      tab.isEditMode = state.isEditMode
      tab.rendered = state.rendered
      tab.loaded = true
    }
  }

  /** 清空所有 tab */
  const clearAll = () => {
    tabs.value = []
    activeTabId.value = null
  }

  // 监听 tabs/activeTabId 变化，防抖持久化
  let _persistTimer: ReturnType<typeof setTimeout> | null = null
  watch([tabs, activeTabId], () => {
    if (_persistTimer) clearTimeout(_persistTimer)
    _persistTimer = setTimeout(persistSession, 1000)
  }, { deep: true })

  return {
    tabs,
    activeTabId,
    activeTab,
    addTab,
    switchTab,
    removeTab,
    cacheCurrentTab,
    clearAll,
    persistSession,
    restoreSession,
    applyUnsavedContent
  }
}
