<template>
  <transition name="slide">
    <div v-show="config.visible" class="sidebar">
      <!-- 服务器区块 -->
      <div class="sidebar-section" :class="{ 'section-on-top': settingsOpen || moreOpenId }">
        <div class="section-header" @click="serverCollapsed = !serverCollapsed">
          <span class="section-title">🖥️ 服务器</span>
          <icon-down v-if="!serverCollapsed" class="section-toggle" />
          <icon-right v-else class="section-toggle" />
        </div>
        <div class="section-content server-content" :class="{ collapsed: serverCollapsed }">
          <!-- 表头 -->
          <div class="server-table-head">
            <span class="col-name">名称</span>
            <span class="col-metric">磁盘</span>
            <span class="col-metric">CPU</span>
            <span class="col-metric">内存</span>
            <span class="col-action settings-btn" @click.stop="settingsOpen = !settingsOpen" title="管理">···</span>
          </div>
          <!-- 表格行 -->
          <div
            v-for="p in profiles"
            :key="p.id"
            class="server-table-row"
            :class="{ active: p.id === activeId }"
            @click="handleSelect(p)"
          >
            <span class="col-name" :title="stateText(p.id)"><span :class="['dot', stateDotClass(p.id)]" />{{ p.name }}</span>
            <span class="col-metric" :title="metricTooltip(p.id, 'disk')">{{ sysInfo(p.id)?.diskUsage || '-' }}</span>
            <span class="col-metric" :title="metricTooltip(p.id, 'cpu')">{{ sysInfo(p.id)?.cpuUsage || '-' }}</span>
            <span class="col-metric" :title="metricTooltip(p.id, 'mem')">{{ sysInfo(p.id)?.memUsage || '-' }}</span>
            <span
              v-if="p.type !== 'local'"
              class="col-action more-btn"
              title="更多操作"
              @click.stop="toggleMore(p.id)"
            >···</span>
            <span v-else class="col-action"></span>
            <!-- 更多操作子菜单 -->
            <div v-if="moreOpenId === p.id" class="more-menu" @click.stop>
              <div class="more-item" @click="handleEdit(p)">编辑</div>
              <div class="more-item danger" @click="handleDelete(p)">删除</div>
            </div>
          </div>

        </div>

        <!-- 管理设置面板（放在 section-content/overflow 容器外部） -->
        <div v-if="settingsOpen" class="settings-panel" @click.stop>
          <div class="settings-item" @click="$emit('openConnectionDialog'); settingsOpen = false">
            <icon-plus /> 添加服务器
          </div>
          <div class="settings-item" @click="toggleAutoConnect">
            <icon-check-circle :style="{ opacity: autoConnect ? 1 : 0.3 }" />
            启动时自动连接所有服务器
          </div>
          <div class="settings-item" @click="toggleAutoRefresh">
            <icon-check-circle :style="{ opacity: autoRefresh ? 1 : 0.3 }" />
            自动刷新系统信息 (15s)
          </div>
        </div>
      </div>

      <!-- 收藏夹区块 -->
      <div class="sidebar-section">
        <div class="section-header" @click="favCollapsed = !favCollapsed">
          <span class="section-title">⭐ 收藏夹</span>
          <span class="section-count">共{{ config.favoriteFiles.length }}项</span>
          <icon-down v-if="!favCollapsed" class="section-toggle" />
          <icon-right v-else class="section-toggle" />
        </div>
        <div class="section-content fav-content" :class="{ collapsed: favCollapsed }">
          <div
            v-for="(fav, index) in config.favoriteFiles"
            :key="fav.path"
            class="sidebar-item"
            :class="{
              'sidebar-item-pinned': fav.pinnedAt,
              'sidebar-item-pinned-first': index === firstPinnedIndex,
              'sidebar-item-pinned-last': index === lastPinnedIndex,
              'sidebar-item-dragging': config.draggingState.isDragging && config.draggingState.draggedIndex === index,
              'sidebar-item-drag-over': config.draggingState.isDragging && config.draggingState.draggedIndex !== index
            }"
            :draggable="config.draggingState.pressedIndex === index || config.draggingState.isDragging"
            @click="handleOpenFavorite(fav)"
            @mousedown="handleLongPressStart($event, index)"
            @mouseup="handleLongPressCancel"
            @mouseleave="handleLongPressCancel"
            @touchstart="handleLongPressStart($event, index)"
            @touchend="handleLongPressCancel"
            @touchcancel="handleLongPressCancel"
            @dragstart="handleDragStart($event, index)"
            @dragover="handleDragOver($event)"
            @drop="handleDrop($event, index)"
            @dragend="handleDragEnd"
          >
            <span class="sidebar-item-icon">{{ getFileIcon(fav) }}</span>
            <span class="sidebar-item-name" :title="fav.name">{{ fav.name }}</span>
            <a-button
              type="text"
              size="mini"
              @click.stop="handleTogglePin(fav)"
              class="sidebar-item-pin"
              :class="{ 'is-pinned': fav.pinnedAt }"
            >
              <template #icon>
                <icon-pushpin :style="{ opacity: fav.pinnedAt ? 1 : 0.4 }" />
              </template>
            </a-button>
            <a-button
              type="text"
              size="mini"
              @click.stop="handleRemoveFavorite(fav)"
              class="sidebar-item-remove"
            >
              <template #icon>
                <icon-close />
              </template>
            </a-button>
          </div>
          <div v-if="config.favoriteFiles.length === 0" class="sidebar-empty">
            <icon-star />
            <span>暂无收藏</span>
            <span class="sidebar-hint">点击文件列表中的星标收藏</span>
          </div>
        </div>
      </div>

      <!-- 帮助文档区块 -->
      <div class="sidebar-section">
        <div class="section-header" @click="helpCollapsed = !helpCollapsed">
          <span class="section-title">📖 帮助</span>
          <icon-down v-if="!helpCollapsed" class="section-toggle" />
          <icon-right v-else class="section-toggle" />
        </div>
        <div class="section-content help-content" :class="{ collapsed: helpCollapsed }">
          <div class="help-item" v-for="item in helpItems" :key="item.key">
            <span class="help-key">{{ item.key }}</span>
            <span class="help-desc">{{ item.desc }}</span>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { ref, computed, shallowRef, onMounted, onUnmounted } from 'vue'
import type { SidebarConfig, FavoriteFile } from '@/types/file-system'
import type { SystemInfo } from '@/api/connection-manager'
import { connectionManager } from '@/api/connection-manager'
import { IconStar, IconClose, IconPushpin, IconDown, IconRight, IconStorage, IconComputer, IconDesktop, IconPlus, IconCheckCircle } from '@arco-design/web-vue/es/icon'
import { getFileIcon } from '@/utils/fileUtils'
import { Message } from '@arco-design/web-vue'

// Props
interface Props {
  config: SidebarConfig
}

const props = defineProps<Props>()

// 折叠状态（组件内部，不污染父组件）
const serverCollapsed = ref(false)
const favCollapsed = ref(false)
const helpCollapsed = ref(false)

// 管理设置
const settingsOpen = ref(false)
const autoConnect = ref(localStorage.getItem('desk:autoConnect') !== 'false')
const autoRefresh = ref(localStorage.getItem('desk:autoRefresh') === 'true')
let refreshTimer: ReturnType<typeof setInterval> | null = null

function toggleAutoConnect() {
  autoConnect.value = !autoConnect.value
  localStorage.setItem('desk:autoConnect', String(autoConnect.value))
}

function toggleAutoRefresh() {
  autoRefresh.value = !autoRefresh.value
  localStorage.setItem('desk:autoRefresh', String(autoRefresh.value))
  if (autoRefresh.value) {
    startAutoRefresh()
  } else {
    stopAutoRefresh()
  }
}

function startAutoRefresh() {
  stopAutoRefresh()
  refreshTimer = setInterval(() => {
    profiles.value.forEach(p => { connectionManager.fetchSystemInfo(p.id).catch(() => {}) })
  }, 15000)
}

function stopAutoRefresh() {
  if (refreshTimer) { clearInterval(refreshTimer); refreshTimer = null }
}

onMounted(() => {
  if (autoRefresh.value) startAutoRefresh()
})
onUnmounted(() => stopAutoRefresh())

// 点击外部关闭更多菜单
function handleClickOutside(e: MouseEvent) {
  const el = e.target as HTMLElement
  if (!el.closest('.server-table-row')) {
    moreOpenId.value = null
  }
  if (!el.closest('.settings-panel') && !el.closest('.settings-btn')) {
    settingsOpen.value = false
  }
}
onMounted(() => document.addEventListener('click', handleClickOutside))
onUnmounted(() => document.removeEventListener('click', handleClickOutside))

// 服务器 Profile 列表状态
const profiles = shallowRef(connectionManager.profiles)
const activeId = shallowRef(connectionManager.activeProfile?.id ?? '')
const moreOpenId = ref<string | null>(null)
const sysInfoMap = ref<Record<string, SystemInfo>>({})

// 监听连接变化 + 系统信息变化
connectionManager.onStateChange(() => {
  profiles.value = connectionManager.profiles
  activeId.value = connectionManager.activeProfile?.id ?? ''
})

connectionManager.onSystemInfoChange((profileId, info) => {
  sysInfoMap.value = { ...sysInfoMap.value, [profileId]: info }
})

// 计算第一个和最后一个置顶项的索引
const pinnedIndices = computed(() => {
  return props.config.favoriteFiles
    .map((fav, index) => fav.pinnedAt ? index : -1)
    .filter(i => i !== -1)
})

const firstPinnedIndex = computed(() => pinnedIndices.value[0] ?? -1)
const lastPinnedIndex = computed(() => pinnedIndices.value[pinnedIndices.value.length - 1] ?? -1)

// 帮助内容
const helpItems = [
  { key: 'Ctrl+B', desc: '切换侧边栏' },
  { key: 'Ctrl+H', desc: '历史记录' },
  { key: 'Ctrl+F', desc: '聚焦搜索' },
  { key: 'Click ⭐', desc: '收藏文件' },
  { key: 'Drag', desc: '排序收藏' },
]

// Emits
interface Emits {
  (e: 'openFavorite', file: FavoriteFile): void
  (e: 'removeFavorite', path: string): void
  (e: 'togglePin', path: string): void
  (e: 'longPressStart', event: MouseEvent | TouchEvent, index: number): void
  (e: 'longPressCancel'): void
  (e: 'dragStart', event: DragEvent, index: number): void
  (e: 'dragOver', event: DragEvent): void
  (e: 'drop', event: DragEvent, targetIndex: number): void
  (e: 'dragEnd'): void
  (e: 'openConnectionDialog', editId?: string): void
}

const emit = defineEmits<Emits>()

// 事件处理
const handleOpenFavorite = (file: FavoriteFile) => {
  emit('openFavorite', file)
}

const handleRemoveFavorite = (file: FavoriteFile) => {
  emit('removeFavorite', file.path)
}

const handleTogglePin = (file: FavoriteFile) => {
  emit('togglePin', file.path)
}

const handleLongPressStart = (event: MouseEvent | TouchEvent, index: number) => {
  emit('longPressStart', event, index)
}

const handleLongPressCancel = () => {
  emit('longPressCancel')
}

const handleDragStart = (event: DragEvent, index: number) => {
  emit('dragStart', event, index)
}

const handleDragOver = (event: DragEvent) => {
  emit('dragOver', event)
}

const handleDrop = (event: DragEvent, targetIndex: number) => {
  emit('drop', event, targetIndex)
}

const handleDragEnd = () => {
  emit('dragEnd')
}

// 服务器操作
function sysInfo(profileId: string): SystemInfo | undefined {
  return sysInfoMap.value[profileId]
}

function stateDotClass(profileId: string): string {
  if (profileId === activeId.value) {
    const state = connectionManager.state
    if (state === 'connected') return 'connected'
    if (state === 'connecting') return 'connecting'
    if (state === 'error') return 'error'
    return 'disconnected'
  }
  const info = sysInfoMap.value[profileId]
  if (info?._error) return 'error'
  if (info && Object.keys(info).length > 1) return 'connected'
  return 'disconnected'
}

function metricTooltip(profileId: string, type: 'disk' | 'cpu' | 'mem'): string {
  const info = sysInfoMap.value[profileId]
  if (!info) return '-'
  if (type === 'disk') {
    const usage = info.diskUsage ? `${info.diskUsage}` : '-'
    const used = info.diskUsed != null ? formatBytes(info.diskUsed) : ''
    const total = info.diskTotal ? formatBytes(info.diskTotal) : ''
    return total ? `${used} / ${total} (${usage})` : usage || '-'
  }
  if (type === 'cpu') {
    const usage = info.cpuUsage ? `${info.cpuUsage}` : '-'
    const cores = info.cpuCores ? `${info.cpuCores} 核` : ''
    return cores ? `${usage} / ${cores}` : usage || '-'
  }
  if (type === 'mem') {
    const usage = info.memUsage ? `${info.memUsage}` : '-'
    const used = info.memUsed != null ? formatBytes(info.memUsed) : ''
    const total = info.memTotal ? formatBytes(info.memTotal) : ''
    return total ? `${used} / ${total} (${usage})` : usage || '-'
  }
  return '-'
}

function formatBytes(n: number): string {
  if (n < 1024) return `${n} B`
  if (n < 1048576) return `${(n / 1024).toFixed(0)} KB`
  if (n < 1073741824) return `${(n / 1048576).toFixed(1)} MB`
  return `${(n / 1073741824).toFixed(1)} GB`
}

function stateText(profileId: string): string {
  if (profileId === activeId.value) {
    const s = connectionManager.state
    if (s === 'connected') return '已连接'
    if (s === 'connecting') return '连接中...'
    if (s === 'error') return '连接失败'
    return '未连接'
  }
  const info = sysInfoMap.value[profileId]
  if (info?._error) return info._errorMsg || '采集失败'
  if (info && Object.keys(info).length > 1) return '已连接'
  return '未连接'
}

async function handleSelect(p: { id: string; type: string }) {
  moreOpenId.value = null
  if (p.id === activeId.value) return
  try {
    await connectionManager.connect(p.id)
  } catch (err) {
    Message.error(`连接失败: ${err instanceof Error ? err.message : String(err)}`)
  }
}

function toggleMore(id: string) {
  moreOpenId.value = moreOpenId.value === id ? null : id
}

function handleEdit(p: { id: string }) {
  moreOpenId.value = null
  emit('openConnectionDialog', p.id)
}

function handleDelete(p: { id: string; name: string }) {
  if (!window.confirm(`确定删除「${p.name}」？`)) return
  connectionManager.removeProfile(p.id)
  moreOpenId.value = null
}
</script>

<style scoped>
.sidebar {
  width: 220px;
  height: 100%;
  background: var(--color-bg-1);
  border-right: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow: hidden;
}

/* 区块 */
.sidebar-section {
  display: flex;
  flex-direction: column;
  position: relative;
}

.sidebar-section.section-on-top {
  z-index: 30;
}

/* 帮助区块固定在底部，不被推出窗口 */
.sidebar-section:last-child {
  flex-shrink: 0;
}

/* 区块头部 - 可点击折叠 */
.section-header {
  padding: 5px 12px;
  background: var(--color-bg-2);
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
  flex-shrink: 0;
}

.section-header:hover {
  background: var(--color-fill-1);
}

.section-title {
  font-size: 13px;
  font-weight: 500;
  color: var(--color-text-1);
}

.section-count {
  font-size: 12px;
  color: var(--color-text-3);
}

.section-toggle {
  font-size: 12px;
  color: var(--color-text-3);
  margin-left: auto;
  transition: transform 0.2s;
}

/* 区块内容 - 可折叠 */
.section-content {
  overflow: hidden;
  transition: max-height 0.25s ease, opacity 0.2s ease;
  max-height: calc(100vh - 80px);
  opacity: 1;
}

.section-content.collapsed {
  max-height: 0;
  opacity: 0;
  padding-top: 0;
  padding-bottom: 0;
}

/* 收藏夹内容 - 内部独立滚动 */
.fav-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 8px 0;
  background: var(--color-bg-2);
  border-radius: 0 0 6px 6px;
}

/* 帮助内容 */
.help-content {
  padding: 4px 12px;
}

.help-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  font-size: 12px;
}

.help-key {
  font-family: 'Consolas', 'Monaco', monospace;
  background: var(--color-fill-2);
  padding: 1px 6px;
  border-radius: 3px;
  color: var(--color-text-2);
  white-space: nowrap;
  min-width: 56px;
  text-align: center;
}

.help-desc {
  color: var(--color-text-3);
}

/* 服务器内容 */
.server-content {
  padding: 2px 4px 6px;
  background: var(--color-fill-1);
  border-radius: 0 0 6px 6px;
  border-left: 3px solid var(--color-primary-6);
  overflow: visible;
}

/* 表头 */
.server-table-head {
  display: flex;
  align-items: center;
  padding: 3px 4px;
  font-size: 11px;
  color: var(--color-text-3);
  border-bottom: 1px solid var(--color-border-2);
  user-select: none;
}
.server-table-head > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 表格行 */
.server-table-row {
  position: relative;
  display: flex;
  align-items: center;
  padding: 4px 4px;
  cursor: pointer;
  font-size: 12px;
  transition: background 0.12s;
}
.server-table-row:hover { background: var(--color-fill-2); }
.server-table-row.active { background: var(--color-primary-light-1); }

.col-name {
  flex: 1;
  min-width: 0;
  color: var(--color-text-1);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 5px;
}
.col-name .dot { flex-shrink: 0; }

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.dot.connected { background: #00b42a; }
.dot.connecting { background: #165dff; animation: pulse 1s infinite; }
.dot.disconnected { background: var(--color-text-4); }
.dot.error { background: #f53f3f; }
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}
.col-metric {
  width: 42px;
  text-align: right;
  flex-shrink: 0;
  font-size: 11px;
  color: var(--color-text-2);
  font-variant-numeric: tabular-nums;
}
.col-action {
  width: 20px;
  flex-shrink: 0;
  text-align: center;
}

/* 更多按钮 */
.more-btn {
  opacity: 0;
  font-size: 14px;
  color: var(--color-text-3);
  cursor: pointer;
  padding: 0 2px;
  line-height: 1;
  letter-spacing: 1px;
  transition: opacity 0.15s;
  user-select: none;
}
.server-table-row:hover .more-btn { opacity: 1; }

/* 更多操作子菜单 */
.more-menu {
  position: absolute;
  right: 4px;
  top: 100%;
  min-width: 80px;
  background: var(--color-bg-popup);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 10;
  padding: 2px 0;
}
.more-item {
  padding: 5px 12px;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.15s;
}
.more-item:hover { background: var(--color-fill-1); }
.more-item.danger { color: var(--color-danger-6); }

/* 设置按钮 */
.settings-btn {
  cursor: pointer;
  font-size: 14px;
  color: var(--color-text-3);
  padding: 0 2px;
  line-height: 1;
  letter-spacing: 1px;
  transition: color 0.15s;
}
.settings-btn:hover { color: var(--color-primary-6); }

/* 设置面板 — 绝对定位浮在按钮下方 */
.settings-panel {
  position: absolute;
  right: 4px;
  top: 50px;
  z-index: 20;
  min-width: 200px;
  background: var(--color-bg-popup);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  padding: 2px 0;
}
.settings-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.12s;
  color: var(--color-text-2);
}
.settings-item:hover { background: var(--color-fill-1); }

/* 区块操作图标 */
.section-action {
  margin-left: auto;
  font-size: 12px;
  color: var(--color-text-3);
  cursor: pointer;
  transition: color 0.15s;
}
.section-action:hover { color: var(--color-primary-6); }

/* 收藏项 */
.sidebar-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.2s;
  user-select: none;
}

.sidebar-item:hover {
  background: var(--color-fill-2);
}

.sidebar-item-dragging {
  opacity: 0.5;
  background: var(--color-fill-1);
}

.sidebar-item-drag-over {
  background: var(--color-fill-3);
  border: 2px dashed var(--color-border-3);
}

.sidebar-item-icon {
  font-size: 18px;
  width: 24px;
  text-align: center;
}

.sidebar-item-name {
  flex: 1;
  font-size: 13px;
  color: var(--color-text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-item-remove {
  opacity: 0;
  transition: opacity 0.2s;
}

.sidebar-item:hover .sidebar-item-remove {
  opacity: 1;
}

.sidebar-item-pinned {
  background: var(--color-fill-1);
  border-radius: 0;
}

.sidebar-item-pinned-first {
  border-radius: 6px 6px 0 0;
}

.sidebar-item-pinned-last {
  border-radius: 0 0 6px 6px;
}

.sidebar-item-pinned-first.sidebar-item-pinned-last {
  border-radius: 6px;
}

.sidebar-item-pin {
  opacity: 0;
  transition: opacity 0.2s;
}

.sidebar-item:hover .sidebar-item-pin {
  opacity: 1;
}

/* 空状态 */
.sidebar-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  text-align: center;
  color: var(--color-text-3);
  gap: 8px;
}

.sidebar-empty :first-child {
  font-size: 48px;
  opacity: 0.5;
}

.sidebar-empty :nth-child(2) {
  font-size: 14px;
}

.sidebar-hint {
  font-size: 12px;
  color: var(--color-text-4);
  margin-top: 4px;
}

/* 侧边栏整体滑入滑出动画 */
.slide-enter-active,
.slide-leave-active {
  transition: all 0.3s ease;
}

.slide-enter-from {
  transform: translateX(-100%);
  opacity: 0;
}

.slide-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}
</style>
