<template>
  <div class="page">
    <div class="page-header">
      <div class="header-left">
        <h2>{{ t('Node Management') }}</h2>
        <p class="page-description">{{ t('Manage and configure your AI node components') }}</p>
      </div>
      <div class="header-right">
        <!-- 搜索 / 筛选 -->
        <div class="filters">
          <n-input
            v-model:value="searchQuery"
            :placeholder="t('Search')"
            clearable
            style="width: 220px"
          />
          <n-select
            v-model:value="statusFilter"
            :options="statusOptions"
            style="width: 160px"
          />
        </div>
        <div class="view-toggle">
          <button 
            class="toggle-btn" 
            :class="{ active: viewMode === 'list' }"
            @click="viewMode = 'list'"
            :title="t('List View')"
          >
            <i class="fa fa-list"></i>
          </button>
          <button 
            class="toggle-btn" 
            :class="{ active: viewMode === 'card' }"
            @click="viewMode = 'card'"
            :title="t('Card View')"
          >
            <i class="fa fa-th-large"></i>
          </button>
        </div>
        <button class="refresh-btn" @click="reload" :disabled="loading">
          <i :class="loading ? 'fa fa-spinner fa-spin' : 'fa fa-refresh'"></i>
        </button>
        <n-dropdown
          trigger="click"
          :options="menuOptions"
          @select="onMenuSelect"
        >
          <button class="refresh-btn" :disabled="loading || importing" :title="t('More')">
            <i :class="importing ? 'fa fa-ellipsis-h fa-spin' : 'fa fa-ellipsis-h'"></i>
          </button>
        </n-dropdown>
        <button 
          v-if="selectedNodes.length === 0"
          class="create-btn" 
          @click="handleCreateNode" 
          :disabled="creating || loading"
        >
          <i class="fa fa-plus"></i>
          {{ t('Create Node') }}
        </button>
        <button 
          v-else
          class="delete-btn" 
          @click="handleDeleteSelected" 
          :disabled="deleting || loading"
        >
          <i class="fa fa-trash"></i>
          {{ t('Delete Selected') }} ({{ selectedNodes.length }})
        </button>
      </div>
    </div>

    <div class="page-content">
      <div v-if="loading" class="loading">
        <i class="fa fa-spinner fa-spin"></i> {{ t('Loading...') }}
      </div>
      <div v-else>
        <!-- 卡片视图 -->
        <div v-if="viewMode === 'card'" class="node-grid">
          <div 
            v-for="node in nodes" 
            :key="node.name" 
            class="node-card" 
            :class="{ selected: selectedNodes.includes(node.name) }"
            @click="toggleNodeSelection(node.name)"
          >
            <div class="card-checkbox">
              <input 
                type="checkbox" 
                :checked="selectedNodes.includes(node.name)"
                @click.stop="toggleNodeSelection(node.name)"
              />
            </div>
            <div class="card-content" @click.stop="openDetail(node.name)">
            <div class="icon" :style="{ color: node.node_color || '#6b7280' }">
              <i :class="resolveIcon(node.node_icon)"></i>
            </div>
            <div class="info">
              <div class="title">{{ node.title || node.type }}</div>
              <div class="desc">{{ node.description || '—' }}</div>
              <div class="meta">
                <span v-if="node.category" class="badge">{{ node.category }}</span>
                  <span v-if="node.status" class="status-badge" :class="node.status">{{ t(node.status) }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 卡片视图分页 -->
        <div v-if="viewMode === 'card'" class="list-pagination">
          <n-pagination v-model:page="page" :page-count="pageCount" size="small" />
        </div>

        <!-- 列表视图 -->
        <div v-else class="node-list">
          <div class="list-header">
            <div class="col-checkbox">
              <input 
                type="checkbox" 
                :checked="selectedNodes.length === nodes.length && nodes.length > 0"
                :indeterminate="selectedNodes.length > 0 && selectedNodes.length < nodes.length"
                @change="toggleSelectAll"
              />
            </div>
            <div class="col-icon">{{ t('Icon') }}</div>
            <div class="col-name">{{ t('Name') }}</div>
            <div class="col-type">{{ t('Type') }}</div>
            <div class="col-category">{{ t('Category') }}</div>
            <div class="col-status">{{ t('Status') }}</div>
            <div class="col-actions">{{ t('Actions') }}</div>
          </div>
          <div class="list-body">
            <div 
              v-for="node in nodes" 
              :key="node.name" 
              class="node-list-item" 
              :class="{ selected: selectedNodes.includes(node.name) }"
              @click="openDetail(node.name)"
            >
              <div class="col-checkbox">
                <input 
                  type="checkbox" 
                  :checked="selectedNodes.includes(node.name)"
                  @click.stop="toggleNodeSelection(node.name)"
                />
              </div>
              <div class="col-icon" @click.stop="openDetail(node.name)">
                <div class="icon" :style="{ color: node.node_color || '#6b7280' }">
                  <i :class="resolveIcon(node.node_icon)"></i>
                </div>
              </div>
              <div class="col-name" @click.stop="openDetail(node.name)">
                <div class="name">{{ node.title || node.type }}</div>
                <div class="description">{{ node.description || '—' }}</div>
              </div>
              <div class="col-type" @click.stop="openDetail(node.name)">{{ node.type }}</div>
              <div class="col-category" @click.stop="openDetail(node.name)">
                <span v-if="node.category" class="badge">{{ node.category }}</span>
              </div>
              <div class="col-status" @click.stop="openDetail(node.name)">
                <span v-if="node.status" class="status-badge" :class="node.status">{{ t(node.status) }}</span>
              </div>
              <div class="col-actions" @click.stop>
                <button class="action-btn" @click="openDetail(node.name)" :title="t('View Details')">
                  <i class="fa fa-eye"></i>
                </button>
              </div>
            </div>
          </div>
          <!-- 分页 -->
          <div class="list-pagination">
            <n-pagination v-model:page="page" :page-count="pageCount" size="small" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { t } from '@/shared/i18n'
import { NInput, NSelect, NPagination, NDropdown, useDialog } from 'naive-ui'
import { getNodeList, importLocalNodes } from '@/shared/api/nodes'

const router = useRouter()
const dialog = useDialog()
const loading = ref(true)
const creating = ref(false)
const deleting = ref(false)
const importing = ref(false)
const nodes = ref<any[]>([])
const allNodes = ref<any[]>([]) // 保存所有原始数据
const total = ref(0)
const selectedNodes = ref<string[]>([])
const viewMode = ref<'card' | 'list'>(
  (localStorage.getItem('nodeListViewMode') as 'card' | 'list') || 'list'
)
const searchQuery = ref('')
const statusFilter = ref('all')
const page = ref(1)
const pageSize = ref(parseInt(localStorage.getItem('itemsPerPage') || '10'))

const statusOptions = computed(() => [
  { label: t('All'), value: 'all' },
  { label: t('Published'), value: 'Published' },
  { label: t('Unpublished'), value: 'Unpublished' },
  { label: t('Draft'), value: 'Draft' }
])

const pageCount = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))

// 顶部菜单
const menuOptions = computed(() => [
  { label: t('Import local nodes'), key: 'import-local-nodes' }
])

function onMenuSelect(key: string) {
  if (key === 'import-local-nodes') {
    handleImportLocalNodes()
  }
}

async function fetchNodes() {
  loading.value = true
  try {
    const result = await getNodeList(page.value, pageSize.value)
    
    allNodes.value = (result.items || []).map((n: any) => ({
      name: n.name,
      type: n.node_type,
      title: n.node_label,
      description: n.node_description,
      category: n.node_group,
      node_icon: n.node_icon,
      node_color: n.node_color,
      properties: {},
      status: n.status,
    }))
    
    // 处理数据（搜索和过滤）
    processNodes()
    total.value = result.total || 0
  } catch (error) {
    console.error('Fetch nodes error:', error)
    nodes.value = []
    allNodes.value = []
    total.value = 0
  } finally {
    loading.value = false
  }
}

function resolveIcon(icon?: string) {
  if (!icon) return 'fa fa-cube'
  if (icon.startsWith('fa-')) return `fa ${icon}`
  return icon
}

function processNodes() {
  let filteredNodes = [...allNodes.value]
  
  // 前端搜索和过滤
  if (searchQuery.value) {
    const query = searchQuery.value.toLowerCase()
    filteredNodes = filteredNodes.filter(node => 
      node.title?.toLowerCase().includes(query) ||
      node.type?.toLowerCase().includes(query) ||
      node.description?.toLowerCase().includes(query) ||
      node.category?.toLowerCase().includes(query)
    )
  }
  
  if (statusFilter.value !== 'all') {
    filteredNodes = filteredNodes.filter(node => node.status === statusFilter.value)
  }
  
  nodes.value = filteredNodes
}

function reload() {
  fetchNodes()
}

// 一键导入本地节点（改为调用后端接口）
async function handleImportLocalNodes() {
  if (importing.value) return
  importing.value = true
  try {
    const res = await importLocalNodes()
    await fetchNodes()
    if (!res?.success) {
      dialog.error({ title: t('Error'), content: t('Import failed') })
      return
    }
    const matchedCount = res.matched || 0
    const importedCount = res.imported || 0
    const skippedExisting = res.skipped_existing || 0
    if (matchedCount === 0) {
      dialog.info({ title: t('Info'), content: t('No local node definitions found') })
    } else if (importedCount === 0 && skippedExisting > 0) {
      dialog.info({ title: t('Info'), content: t('All local nodes already exist') })
    } else if (importedCount > 0) {
      dialog.success({ title: t('Success'), content: `${t('Imported')} ${importedCount} ${t('nodes')}` })
    } else {
      dialog.info({ title: t('Info'), content: t('No new local nodes found') })
    }
  } catch (e) {
    console.error('Import local nodes error:', e)
    dialog.error({ title: t('Error'), content: t('Import failed') })
  } finally {
    importing.value = false
  }
}

// 选择相关函数
function toggleNodeSelection(nodeName: string) {
  const index = selectedNodes.value.indexOf(nodeName)
  if (index > -1) {
    selectedNodes.value.splice(index, 1)
  } else {
    selectedNodes.value.push(nodeName)
  }
}

function toggleSelectAll() {
  if (selectedNodes.value.length === nodes.value.length) {
    selectedNodes.value = []
  } else {
    selectedNodes.value = nodes.value.map(node => node.name)
  }
}

async function handleDeleteSelected() {
  if (selectedNodes.value.length === 0) return
  
  dialog.error({
    title: t('Confirm Delete'),
    content: t('Are you sure you want to delete the selected nodes? This action cannot be undone.'),
    positiveText: t('Delete'),
    negativeText: t('Cancel'),
    onPositiveClick: async () => {
      deleting.value = true
      try {
        const { deleteNodes } = await import('@/shared/api/nodes')
        const result = await deleteNodes(selectedNodes.value)
        
        if (result.success) {
          // 删除成功，重新加载数据
          selectedNodes.value = []
          await fetchNodes()
        } else {
          alert(t('Delete failed') + ': ' + (result.message || t('Unknown error')))
        }
      } catch (error) {
        console.error('Delete error:', error)
        alert(t('Delete failed') + ': ' + t('Network error'))
      } finally {
        deleting.value = false
      }
    }
  })
}

// 监听搜索和筛选变化
watch([searchQuery, statusFilter], () => {
  page.value = 1 // 重置到第一页
  // 重新处理数据，不需要重新请求API
  processNodes()
}, { deep: true })

// 监听分页变化
watch([page], () => {
  fetchNodes()
})

// 监听每页数量变化（从系统设置）
watch(() => localStorage.getItem('itemsPerPage'), (newValue) => {
  if (newValue) {
    pageSize.value = parseInt(newValue)
    page.value = 1 // 重置到第一页
    fetchNodes()
  }
})

// 监听视图模式变化并持久化
watch(viewMode, (m) => {
  localStorage.setItem('nodeListViewMode', m)
})

function openDetail(name: string) {
  router.push({ name: 'NodeDetail', params: { name } })
}

function handleCreateNode() {
  // 仅跳转到新建模式，由详情页保存时再创建后端记录
  router.push({ name: 'NodeDetail', params: { name: 'new' } })
}

onMounted(() => {
  fetchNodes()
})
</script>

<style scoped>
.page { 
  padding: 16px; 
  width: 100%;
  min-height: 100vh;
}

.page-header { 
  display: flex; 
  align-items: flex-start; 
  justify-content: space-between; 
  margin-bottom: 24px; 
}

.header-left h2 {
  font-size: 28px;
  font-weight: 700;
  color: #1f2937;
  margin: 0 0 8px 0;
}

.page-description {
  font-size: 16px;
  color: #6b7280;
  margin: 0;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.filters { 
  display: flex; 
  gap: 8px; 
  align-items: center; 
}

.view-toggle {
  display: flex;
  background: #f8fafc;
  border-radius: 8px;
  padding: 2px;
  border: 1px solid #e2e8f0;
}

.toggle-btn {
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  color: #64748b;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  border-radius: 6px;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.toggle-btn:hover {
  background: #e2e8f0;
  color: #475569;
}

.toggle-btn.active {
  background: #3b82f6;
  color: white;
  box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2);
}

.toggle-btn.active:hover {
  background: #2563eb;
}

/* 现代化刷新按钮 */
.refresh-btn {
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 8px;
  background: #f8fafc;
  color: #64748b;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.refresh-btn:hover {
  background: #e2e8f0;
  color: #475569;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.refresh-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

.refresh-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.refresh-btn:disabled:hover {
  background: #f8fafc;
  color: #64748b;
  transform: none;
  box-shadow: none;
}

/* 微妙的脉冲效果 */
.refresh-btn:not(:disabled):hover::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  background: rgba(59, 130, 246, 0.1);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  animation: pulse 0.6s ease-out;
}

@keyframes pulse {
  0% {
    width: 0;
    height: 0;
    opacity: 1;
  }
  100% {
    width: 40px;
    height: 40px;
    opacity: 0;
  }
}
/* 卡片视图样式 */
.node-grid { 
  display: grid; 
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 
  gap: 16px; 
}

.node-card { 
  position: relative;
  padding: 16px; 
  border: 1px solid #e5e7eb; 
  border-radius: 12px; 
  cursor: pointer; 
  background: #fff; 
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.node-card:hover { 
  border-color: #3b82f6; 
  background: #f8fafc; 
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.card-content {
  display: flex;
  gap: 12px;
  width: 100%;
}

.icon { 
  width: 48px; 
  height: 48px; 
  border-radius: 12px; 
  display: flex; 
  align-items: center; 
  justify-content: center; 
  background: #f3f4f6; 
  font-size: 20px; 
  flex-shrink: 0;
}

.info { 
  flex: 1; 
  min-width: 0;
  padding-right: 30px; /* 为复选框留出空间 */
}

.title { 
  font-weight: 600; 
  color: #111827; 
  margin-bottom: 4px; 
  font-size: 16px;
}

.desc { 
  color: #6b7280; 
  font-size: 13px; 
  line-height: 1.4; 
  height: 36px; 
  overflow: hidden; 
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.meta { 
  margin-top: 8px; 
  display: flex; 
  gap: 8px; 
  flex-wrap: wrap;
}

.badge { 
  background: #eef2ff; 
  color: #334155; 
  padding: 4px 8px; 
  border-radius: 6px; 
  font-size: 11px; 
  font-weight: 500;
}

.status-badge {
  padding: 4px 8px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 500;
}

.status-badge.active {
  background: #dcfce7;
  color: #166534;
}

.status-badge.inactive {
  background: #fee2e2;
  color: #991b1b;
}

.status-badge.draft {
  background: #fef3c7;
  color: #92400e;
}

.status-badge.published {
  background: #dcfce7;
  color: #166534;
}

.status-badge.unpublished {
  background: #fee2e2;
  color: #991b1b;
}

/* 列表视图样式 */
.node-list {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  width: 100%;
}

.list-header {
  display: grid;
  grid-template-columns: 40px 60px 2fr 1fr 1fr 1fr 80px;
  gap: 16px;
  padding: 16px 20px;
  background: #f8fafc;
  border-bottom: 1px solid #e5e7eb;
  font-weight: 600;
  color: #374151;
  font-size: 14px;
}

.list-body {
  max-height: 600px;
  overflow-y: auto;
}

.list-pagination {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid #f3f4f6;
}

.node-list-item {
  display: grid;
  grid-template-columns: 40px 60px 2fr 1fr 1fr 1fr 80px;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid #f3f4f6;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.node-list-item:hover {
  background: #f8fafc;
}

.node-list-item:last-child {
  border-bottom: none;
}

.col-icon {
  display: flex;
  align-items: center;
}

.col-icon .icon {
  width: 36px;
  height: 36px;
  font-size: 16px;
}

.col-name {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}

.col-name .name {
  font-weight: 600;
  color: #111827;
  font-size: 14px;
  margin-bottom: 2px;
}

.col-name .description {
  color: #6b7280;
  font-size: 12px;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.col-type {
  display: flex;
  align-items: center;
  color: #6b7280;
  font-size: 13px;
}

.col-category {
  display: flex;
  align-items: center;
}

.col-status {
  display: flex;
  align-items: center;
}

.col-actions {
  display: flex;
  align-items: center;
  justify-content: center;
}

.action-btn {
  width: 28px;
  height: 28px;
  border: none;
  background: #f3f4f6;
  color: #6b7280;
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.action-btn:hover {
  background: #3b82f6;
  color: white;
}

/* 新建按钮 */
.create-btn {
  height: 36px;
  padding: 0 16px;
  border: none;
  border-radius: 8px;
  background: #2563eb;
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.create-btn:hover {
  background: #1d4ed8;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
}

.create-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.3);
}

.create-btn i {
  font-size: 12px;
}

.delete-btn {
  background: #ef4444;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.delete-btn:hover {
  background: #dc2626;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3);
}

.delete-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(239, 68, 68, 0.3);
}

.delete-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.delete-btn i {
  font-size: 12px;
}

/* 选择相关样式 */
.col-checkbox {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
}

.card-checkbox {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 10;
}

.card-checkbox input[type="checkbox"] {
  cursor: pointer;
  accent-color: #3b82f6;
}

.node-card.selected {
  border-color: #3b82f6;
  background: #f0f9ff;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

.node-list-item.selected {
  background: #f0f9ff;
  border-color: #3b82f6;
}
</style>

