<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
import { portalApi } from '../api'
import '../styles/portal.css'

const loading = ref(true)
const settings = ref({})
const categories = ref([])
const links = ref([])

const activeCatId = ref(null)
const selections = ref({})   // { rowId: optionId }
const resources = ref([])
const resLoading = ref(false)
const copiedKey = ref('')

// Search
const searchMode = ref(false)
const searchKeyword = ref('')
const searchResults = ref([])
const searchLoading = ref(false)
const searchDebounce = ref(null)

async function doSearch() {
  const kw = searchKeyword.value.trim()
  if (!kw || kw.length < 2) {
    searchResults.value = []
    return
  }
  searchLoading.value = true
  try {
    const { data } = await portalApi.search(kw)
    searchResults.value = data.results || []
  } finally {
    searchLoading.value = false
  }
}

function onSearchInput() {
  clearTimeout(searchDebounce.value)
  searchDebounce.value = setTimeout(doSearch, 300)
}

function openSearch() {
  searchMode.value = true
  searchKeyword.value = ''
  searchResults.value = []
}

function closeSearch() {
  searchMode.value = false
  searchKeyword.value = ''
  searchResults.value = []
}

const activeCat = computed(() => categories.value.find(c => c.id === activeCatId.value) || null)

const stats = computed(() => ({
  categories: categories.value.length,
  links: links.value.length
}))

async function loadBootstrap() {
  loading.value = true
  try {
    const { data } = await portalApi.bootstrap()
    settings.value = data.settings || {}
    categories.value = data.categories || []
    links.value = data.links || []
    document.title = settings.value.site_name || 'OPS 资源中心'
    if (categories.value.length && !activeCatId.value) {
      selectCategory(categories.value[0].id)
    }
  } finally {
    loading.value = false
  }
}

function selectCategory(id) {
  activeCatId.value = id
  selections.value = {}
  loadResources()
}

function toggleOption(rowId, optId) {
  if (selections.value[rowId] === optId) {
    delete selections.value[rowId]
  } else {
    selections.value[rowId] = optId
  }
  selections.value = { ...selections.value }
  loadResources()
}

async function loadResources() {
  if (!activeCatId.value) return
  resLoading.value = true
  try {
    const ids = Object.values(selections.value)
    const { data } = await portalApi.resources(activeCatId.value, ids)
    resources.value = data.resources || []
  } catch {
    resources.value = []
  } finally {
    resLoading.value = false
  }
}

async function copyText(text, key) {
  try {
    await navigator.clipboard.writeText(text)
  } catch {
    const ta = document.createElement('textarea')
    ta.value = text
    document.body.appendChild(ta)
    ta.select()
    document.execCommand('copy')
    document.body.removeChild(ta)
  }
  copiedKey.value = key
  setTimeout(() => { if (copiedKey.value === key) copiedKey.value = '' }, 1600)
}

const typeLabel = { command: 'CMD', link: 'LINK', text: 'DOC', file: 'FILE' }

onMounted(() => {
  loadBootstrap()
  // Keyboard shortcut for search
  const handleKeydown = (e) => {
    if (e.key === '/' && !searchMode.value && !['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) {
      e.preventDefault()
      openSearch()
      setTimeout(() => document.querySelector('.search-input')?.focus(), 50)
    }
    if (e.key === 'Escape' && searchMode.value) {
      closeSearch()
    }
  }
  window.addEventListener('keydown', handleKeydown)
  onBeforeUnmount(() => window.removeEventListener('keydown', handleKeydown))
})
</script>

<template>
  <div class="portal">
    <!-- announcement ticker -->
    <div class="ticker" v-if="settings.announcement">
      <div class="ticker-inner">
        <span v-for="i in 2" :key="i"><b>公告</b>{{ settings.announcement }}</span>
      </div>
    </div>

    <!-- hero -->
    <header class="hero">
      <div class="hero-grid-bg"></div>
      <div class="hero-inner">
        <div class="hero-left">
          <div class="hero-tag">{{ settings.hero_tag || 'INTERNAL RESOURCES' }}</div>
          <h1 v-html="(settings.hero_title || '内部资源 快速上手').replace(/(快速上手|GET STARTED)/, '<em>$1</em>')"></h1>
          <p class="hero-sub">{{ settings.hero_subtitle }}</p>

          <!-- Search button in hero -->
          <div class="hero-search-btn" @click="openSearch">
            <span class="hs-icon">🔍</span>
            搜索内部资源
            <span class="hs-hint">按 / 快速搜索</span>
          </div>

          <div class="terminal" v-if="settings.hero_command">
            <div class="terminal-bar">
              <i></i><i></i><i></i>
              <span>{{ settings.hero_command_label || 'RUN THE COMMAND TO INSTALL' }}</span>
            </div>
            <div class="terminal-body">
              <code>{{ settings.hero_command }}</code>
              <button class="copy-btn" :class="{ copied: copiedKey === 'hero' }"
                      @click="copyText(settings.hero_command, 'hero')">
                {{ copiedKey === 'hero' ? '✓ 已复制' : '复制' }}
              </button>
            </div>
          </div>

          <div class="hero-stats">
            <div class="hero-stat"><b>{{ stats.categories }}</b><span>资源分类</span></div>
            <div class="hero-stat"><b>{{ stats.links }}</b><span>快捷入口</span></div>
            <div class="hero-stat"><b>24/7</b><span>内部可用</span></div>
          </div>
        </div>

        <div class="hero-art">
          <svg viewBox="0 0 460 380" preserveAspectRatio="xMidYMid meet">
            <path class="trace" d="M20,60 H160 V150 H300 V60 H440" />
            <path class="trace" d="M20,190 H110 V290 H250 V190 H440" />
            <path class="trace" d="M60,20 V120 H220 V330 H400 V240" />
            <path class="trace-flow" d="M20,60 H160 V150 H300 V60 H440" />
            <path class="trace-flow" d="M20,190 H110 V290 H250 V190 H440" style="animation-delay:-2s" />
            <path class="trace-flow" d="M60,20 V120 H220 V330 H400 V240" style="animation-delay:-3.4s" />
            <g v-for="(p, i) in [[160,60],[300,60],[110,190],[250,190],[220,120],[400,240],[160,150],[250,290]]" :key="i">
              <rect class="node" :x="p[0]-7" :y="p[1]-7" width="14" height="14" rx="2" />
              <circle class="node-core" :cx="p[0]" :cy="p[1]" r="3" :style="{ animationDelay: (-i * .35) + 's' }" />
            </g>
          </svg>
          <div class="cube c1"></div>
          <div class="cube c2"></div>
          <div class="cube c3"></div>
          <div class="cube c4"></div>
        </div>
      </div>
    </header>

    <!-- Search overlay -->
    <div class="search-overlay" v-if="searchMode" @click.self="closeSearch">
      <div class="search-modal">
        <div class="search-input-wrap">
          <span class="search-icon">🔍</span>
          <input type="text" v-model="searchKeyword" placeholder="搜索资源标题、内容..."
                 class="search-input" @input="onSearchInput" ref="searchInput">
          <button class="search-close" @click="closeSearch">✕</button>
        </div>
        <div class="search-results" v-loading="searchLoading">
          <div v-if="searchKeyword.length && searchKeyword.length < 2" class="search-hint">
            请输入至少 2 个字符
          </div>
          <div v-else-if="!searchLoading && !searchResults.length && searchKeyword.length >= 2" class="search-empty">
            未找到相关资源
          </div>
          <div v-for="res in searchResults" :key="res.id" class="search-result-item"
               @click="selectCategory(res.category_id); closeSearch()">
            <span class="res-badge-sm" :class="res.type">{{ typeLabel[res.type] || res.type }}</span>
            <span class="sr-title">{{ res.title }}</span>
            <span class="sr-desc" v-if="res.description">{{ res.description }}</span>
          </div>
        </div>
        <div class="search-footer">
          <kbd>ESC</kbd> 关闭 &nbsp;&nbsp; <kbd>↑</kbd><kbd>↓</kbd> 导航
        </div>
      </div>
    </div>

    <!-- content -->
    <div class="loading-wrap" v-if="loading">正在加载资源…</div>

    <main class="content-wrap" v-else>
      <!-- left menu -->
      <nav class="side-menu">
        <div class="side-menu-title">CATEGORIES</div>
        <div v-for="cat in categories" :key="cat.id"
             class="menu-item" :class="{ active: cat.id === activeCatId }"
             @click="selectCategory(cat.id)">
          <span class="mi-icon">{{ cat.icon }}</span>
          <span>{{ cat.name }}</span>
          <span class="mi-count">{{ cat.resource_count }}</span>
        </div>
      </nav>

      <!-- center -->
      <section class="center-panel">
        <div class="panel-head" v-if="activeCat">
          <h2>{{ activeCat.icon }} {{ activeCat.name }}</h2>
          <p>{{ activeCat.description }}</p>
        </div>

        <!-- option tiles -->
        <div v-for="row in (activeCat?.rows || [])" :key="row.id" class="option-row">
          <div class="option-row-title">{{ row.title }}</div>
          <div class="tiles">
            <div v-for="opt in row.options" :key="opt.id"
                 class="tile" :class="{ selected: selections[row.id] === opt.id }"
                 @click="toggleOption(row.id, opt.id)">
              <span class="tile-icon" v-if="opt.icon">{{ opt.icon }}</span>
              {{ opt.label }}
            </div>
          </div>
        </div>

        <!-- resources -->
        <div class="res-list" v-if="resources.length">
          <article v-for="(res, idx) in resources" :key="res.id" class="res-card"
                   :style="{ animationDelay: (idx * 60) + 'ms' }">
            <div class="res-head">
              <span class="res-badge" :class="res.type">{{ typeLabel[res.type] || res.type }}</span>
              <span class="res-title">{{ res.title }}</span>
              <span class="res-desc" v-if="res.description">{{ res.description }}</span>
            </div>

            <div v-if="res.type === 'command'" class="cmd-block">
              <code>{{ res.content }}</code>
              <button class="cmd-copy" :class="{ copied: copiedKey === 'res' + res.id }"
                      @click="copyText(res.content, 'res' + res.id)">
                {{ copiedKey === 'res' + res.id ? '✓ 已复制' : '复制' }}
              </button>
            </div>

            <template v-else-if="res.type === 'link'">
              <div class="res-body" v-if="res.content">{{ res.content }}</div>
              <a class="res-jump" :href="res.url" target="_blank" rel="noopener">
                {{ res.url }} &nbsp;跳转 →
              </a>
            </template>

            <template v-else-if="res.type === 'file'">
              <div class="res-body" v-if="res.content">{{ res.content }}</div>
              <a class="res-jump" :href="res.url" target="_blank" rel="noopener">下载文件 ↓</a>
            </template>

            <div v-else class="res-body">{{ res.content }}</div>
          </article>
        </div>

        <div class="empty-hint" v-else-if="!resLoading">
          <span class="eh-icon">📭</span>
          该分类下暂无资源，请在管理后台添加
        </div>
      </section>

      <!-- right links -->
      <aside class="links-panel" v-if="links.length">
        <h3>其他链接</h3>
        <a v-for="l in links" :key="l.id" class="link-item" :href="l.url" target="_blank" rel="noopener">
          {{ l.title }}
        </a>
      </aside>
    </main>

    <footer class="portal-footer">
      {{ settings.footer_text || 'OPS Resource Portal' }}
      <router-link to="/admin">管理后台</router-link>
    </footer>

    <router-link to="/admin" class="admin-fab" title="管理后台">⚙</router-link>
  </div>
</template>
