<template>
  <aside class="chat-sidebar">
    <div class="sidebar-header">
      <span class="title">会话</span>
      <n-button size="small" type="primary" @click="$emit('new')">+ 新建</n-button>
    </div>
    <n-scrollbar class="sidebar-list">
      <div
        v-for="s in sessions"
        :key="s.id"
        class="session-item"
        :class="{
          active: s.id === currentSessionId,
          pinned: !!s.pinned,
          running: hasActiveRunFn(s.id)
        }"
        @click="$emit('select', s.id)"
      >
        <div class="session-title">
          <n-icon v-if="s.pinned" :component="PinOutline" class="pin-marker" title="已置顶" />
          <span class="session-title-text">{{ formatTitle(s.title) }}</span>
        </div>
        <div class="session-meta">
          <span>{{ formatTime(s.lastMessageAt) }}</span>
        </div>
        <!-- 操作区：loading 在左、⋯ 在右；点击操作区不冒泡到 select -->
        <div class="session-ops" @click.stop>
          <n-spin v-if="hasActiveRunFn(s.id)" :size="12" class="run-indicator" />
          <n-dropdown
            trigger="click"
            :options="menuOptions(s)"
            placement="bottom-end"
            @select="(key) => onMenuSelect(key, s)"
          >
            <button class="more-btn" title="更多操作" @click.stop>
              <n-icon :component="EllipsisHorizontal" :size="16" />
            </button>
          </n-dropdown>
        </div>
      </div>
      <n-empty v-if="!sessions.length" description="暂无会话" style="margin-top: 40px" />
    </n-scrollbar>

    <!-- 重命名弹窗：preset=dialog，回车也可提交 -->
    <n-modal
      v-model:show="renameModalShow"
      preset="dialog"
      title="重命名会话"
      :show-icon="false"
      positive-text="保存"
      negative-text="取消"
      @positive-click="submitRename"
      style="width: 420px;"
    >
      <n-input
        v-model:value="renameValue"
        placeholder="请输入新名称"
        maxlength="50"
        @keydown.enter="submitRename"
      />
    </n-modal>
  </aside>
</template>

<script setup>
import { ref } from 'vue'
import {
  NButton,
  NScrollbar,
  NEmpty,
  NSpin,
  NDropdown,
  NModal,
  NInput,
  NIcon,
  useDialog
} from 'naive-ui'
import { PinOutline, EllipsisHorizontal } from '@vicons/ionicons5'

defineProps({
  sessions: { type: Array, default: () => [] },
  currentSessionId: { type: [Number, String], default: null },
  hasActiveRunFn: { type: Function, required: true }
})

const emit = defineEmits(['select', 'new', 'delete', 'rename', 'toggle-pin'])

const dialog = useDialog()

/* ============== 重命名弹窗状态 ============== */
const renameModalShow = ref(false)
const renameTargetId = ref(null)
const renameValue = ref('')

/* ============== 三点菜单 ============== */

function menuOptions(s) {
  return [
    { label: '重命名', key: 'rename' },
    { label: s.pinned ? '取消置顶' : '置顶', key: 'pin' },
    { type: 'divider', key: 'd1' },
    {
      label: '删除',
      key: 'delete',
      props: { style: { color: '#f87171' } }
    }
  ]
}

function onMenuSelect(key, s) {
  if (key === 'rename') {
    openRenameModal(s)
  } else if (key === 'pin') {
    emit('toggle-pin', s.id, !!s.pinned)
  } else if (key === 'delete') {
    confirmDelete(s)
  }
}

function openRenameModal(s) {
  renameTargetId.value = s.id
  renameValue.value = s.title || ''
  renameModalShow.value = true
}

function submitRename() {
  const title = (renameValue.value || '').trim()
  if (!title) return false
  emit('rename', renameTargetId.value, title)
  return true
}

function confirmDelete(s) {
  dialog.warning({
    title: '删除会话',
    content: `确定删除「${formatTitle(s.title)}」？删除后会话归档，数据保留供审计。`,
    positiveText: '删除',
    negativeText: '取消',
    onPositiveClick: () => emit('delete', s.id)
  })
}

/* ============== 工具 ============== */

function formatTitle(title) {
  if (!title) return '新会话'
  return title.length > 24 ? title.slice(0, 24) + '…' : title
}

function formatTime(ts) {
  if (!ts) return ''
  // ts 可能是 ISO 字符串或数组（Java LocalDateTime 序列化）
  const d = Array.isArray(ts) ? new Date(...ts.slice(0, 6)) : new Date(ts)
  if (isNaN(d.getTime())) return ''
  const now = new Date()
  const sameDay = d.toDateString() === now.toDateString()
  return sameDay
    ? d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
    : d.toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' })
}
</script>

<style scoped>
/* v1.3：深色主题，与系统深色风格一致；不再用 naive-ui 的 --n-color（白色） */
.chat-sidebar {
  width: 260px;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, 0.2);
}
.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.sidebar-header .title {
  font-weight: 600;
  font-size: 14px;
  color: var(--text-primary, #e0e0e0);
}
.sidebar-list {
  flex: 1;
}
.session-item {
  padding: 10px 16px;
  cursor: pointer;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  position: relative;
  transition: background 0.15s;
}
.session-item:hover {
  background: rgba(255, 255, 255, 0.04);
}
.session-item.active {
  background: rgba(168, 85, 247, 0.12);
}
/* 激活态左侧紫色竖条，强化"当前选中"视觉 */
.session-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: #c084fc;
}
.session-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-primary, #e0e0e0);
  padding-right: 50px; /* 给 loading + ⋯ 留位置 */
}
.session-title-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pin-marker {
  flex-shrink: 0;
  color: #f59e0b;
  font-size: 12px;
}
.session-meta {
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-tertiary, #888);
}

/* 操作区：loading + ⋯，绝对定位在右上角 */
.session-ops {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  align-items: center;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.15s;
}
/* RUNNING 中：loading 始终可见；非 RUNNING：hover 才显示按钮 */
.session-item.running .session-ops,
.session-item:hover .session-ops {
  opacity: 1;
}
.run-indicator {
  flex-shrink: 0;
}
.more-btn {
  width: 22px;
  height: 22px;
  border: none;
  background: transparent;
  color: var(--text-tertiary, #888);
  border-radius: 3px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: all 0.15s;
}
.more-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-primary, #e0e0e0);
}
</style>
