<script setup lang="ts">
import { computed, ref, onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useConnectionsStore } from '../stores/connections'
import { useSftpTabsStore } from '../stores/sftpTabs'
import { useTerminalTabsStore } from '../stores/terminalTabs'
import type { Connection, ConnectionCreateRequest } from '../api/connections'
import ConnectionForm from '../components/ConnectionForm.vue'
import {
  Server,
  Plus,
  Terminal,
  FolderOpen,
  Pencil,
  Trash2,
  Key,
  Lock,
  Search,
  X,
} from 'lucide-vue-next'

const router = useRouter()
const route = useRoute()
const store = useConnectionsStore()
const tabsStore = useTerminalTabsStore()
const sftpTabsStore = useSftpTabsStore()

const showForm = ref(false)
const editingConn = ref<Connection | null>(null)
const searchQuery = ref('')

const keyword = computed(() => route.query.q as string || '')
const filteredConnections = computed(() => {
  const q = keyword.value.trim().toLowerCase()

  if (!q) {
    return store.connections
  }

  return store.connections.filter((conn) => {
    const fields = [
      conn.name,
      conn.host,
      conn.username,
      String(conn.port),
    ]

    return fields.some((field) => field.toLowerCase().includes(q))
  })
})

const updateSearchParam = (value: string) => {
  router.push({ query: { ...route.query, q: value } })
}

onMounted(() => {
  searchQuery.value = keyword.value
  store.fetchConnections()
})

watch(searchQuery, (val) => {
  updateSearchParam(val)
})

function openCreate() {
  editingConn.value = null
  showForm.value = true
}

function openEdit(conn: Connection) {
  editingConn.value = conn
  showForm.value = true
}

function closeForm() {
  showForm.value = false
  editingConn.value = null
}

async function handleSave(data: ConnectionCreateRequest) {
  if (editingConn.value) {
    await store.updateConnection(editingConn.value.id, data)
  } else {
    await store.createConnection(data)
  }
  closeForm()
}

async function handleDelete(conn: Connection) {
  if (!confirm(`确定删除连接「${conn.name}」？`)) return
  await store.deleteConnection(conn.id)
}

function openTerminal(conn: Connection) {
  tabsStore.openTab(conn)
  router.push('/terminal')
}

function openSftp(conn: Connection) {
  sftpTabsStore.openOrFocus(conn)
  router.push(`/sftp/${conn.id}`)
}

function clearSearch() {
  searchQuery.value = ''
  updateSearchParam('')
}

function highlightMatch(text: string): string {
  const q = keyword.value.trim()
  if (!q) return text
  
  const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  const regex = new RegExp(escaped, 'gi')
  
  return text.replace(regex, (match) => `<span class="text-cyan-300 font-semibold">${match}</span>`)
}
</script>

<template>
  <div class="p-6">
    <div class="flex items-center justify-between mb-6">
      <h2 class="text-xl font-semibold text-slate-100">连接列表</h2>
      <button
        @click="openCreate"
        class="flex items-center gap-2 px-4 py-2 rounded-lg bg-cyan-600 hover:bg-cyan-500 text-white font-medium transition-colors duration-200 cursor-pointer"
        aria-label="添加连接"
      >
        <Plus class="w-5 h-5" aria-hidden="true" />
        添加连接
      </button>
    </div>

    <div class="relative mb-6">
      <Search class="w-4 h-4 text-slate-500 absolute left-3 top-1/2 -translate-y-1/2" aria-hidden="true" />
      <input
        v-model="searchQuery"
        type="text"
        placeholder="搜索名称、主机、用户名或端口"
        class="w-full rounded-xl border border-slate-700 bg-slate-800/70 py-3 pl-10 pr-11 text-slate-100 placeholder:text-slate-500 focus:border-cyan-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/20"
        aria-label="搜索连接"
      />
      <button
        v-if="searchQuery"
        @click="clearSearch"
        class="absolute right-3 top-1/2 -translate-y-1/2 rounded-md p-1 text-slate-400 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer"
        aria-label="清空搜索"
      >
        <X class="w-4 h-4" aria-hidden="true" />
      </button>
    </div>

    <div v-if="store.connections.length === 0" class="text-center py-16 bg-slate-800/50 rounded-xl border border-slate-700">
      <Server class="w-16 h-16 text-slate-500 mx-auto mb-4" aria-hidden="true" />
      <p class="text-slate-400 mb-4">暂无连接</p>
      <button
        @click="openCreate"
        class="px-4 py-2 rounded-lg bg-cyan-600 hover:bg-cyan-500 text-white transition-colors duration-200 cursor-pointer"
      >
        添加第一个连接
      </button>
    </div>

    <div
      v-else-if="filteredConnections.length === 0"
      class="text-center py-16 bg-slate-800/50 rounded-xl border border-slate-700"
    >
      <Search class="w-16 h-16 text-slate-500 mx-auto mb-4" aria-hidden="true" />
      <p class="text-slate-300 mb-2">未找到匹配的连接</p>
      <p class="text-sm text-slate-500 mb-4">试试搜索名称、主机、用户名或端口</p>
      <button
        @click="clearSearch"
        class="px-4 py-2 rounded-lg bg-slate-700 hover:bg-slate-600 text-slate-200 transition-colors duration-200 cursor-pointer"
      >
        清空搜索
      </button>
    </div>

    <div v-else class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
      <div
        v-for="conn in filteredConnections"
        :key="conn.id"
        class="bg-slate-800 rounded-xl border border-slate-700 p-4 hover:border-slate-600 transition-colors duration-200"
      >
        <div class="flex items-start justify-between mb-3">
          <div class="flex items-center gap-2">
            <div class="w-10 h-10 rounded-lg bg-slate-700 flex items-center justify-center">
              <Server class="w-5 h-5 text-cyan-400" aria-hidden="true" />
            </div>
            <div>
              <h3 class="font-medium text-slate-100" v-html="highlightMatch(conn.name)"></h3>
              <p class="text-sm text-slate-400" v-html="highlightMatch(`${conn.username}@${conn.host}:${conn.port}`)"></p>
            </div>
          </div>
          <div class="flex items-center gap-1">
            <button
              @click="openEdit(conn)"
              class="p-2 rounded-lg text-slate-400 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer"
              aria-label="编辑"
            >
              <Pencil class="w-4 h-4" aria-hidden="true" />
            </button>
            <button
              @click="handleDelete(conn)"
              class="p-2 rounded-lg text-slate-400 hover:bg-red-900/50 hover:text-red-400 transition-colors duration-200 cursor-pointer"
              aria-label="删除"
            >
              <Trash2 class="w-4 h-4" aria-hidden="true" />
            </button>
          </div>
        </div>
        <div class="flex items-center gap-2 mb-3">
          <component
            :is="conn.authType === 'PRIVATE_KEY' ? Key : Lock"
            class="w-4 h-4 text-slate-500"
            aria-hidden="true"
          />
          <span class="text-sm text-slate-500">{{ conn.authType === 'PRIVATE_KEY' ? '私钥' : '密码' }}</span>
        </div>
        <div class="flex gap-2">
          <button
            @click="openTerminal(conn)"
            class="flex-1 flex items-center justify-center gap-2 py-2 rounded-lg bg-slate-700 hover:bg-slate-600 text-slate-300 hover:text-slate-100 transition-colors duration-200 cursor-pointer text-sm"
          >
            <Terminal class="w-4 h-4" aria-hidden="true" />
            终端
          </button>
          <button
            @click="openSftp(conn)"
            class="flex-1 flex items-center justify-center gap-2 py-2 rounded-lg bg-slate-700 hover:bg-slate-600 text-slate-300 hover:text-slate-100 transition-colors duration-200 cursor-pointer text-sm"
          >
            <FolderOpen class="w-4 h-4" aria-hidden="true" />
            文件
          </button>
        </div>
      </div>
    </div>

    <ConnectionForm
      v-if="showForm"
      :connection="editingConn"
      :on-save="handleSave"
      @close="closeForm"
    />
  </div>
</template>
