<template>
  <div class="search-view">
    <h1>Search</h1>

    <div class="search-bar">
      <input v-model="query" @keyup.enter="search"
             placeholder="Enter search query..."
             :disabled="loading" />
      <select v-model="mode" class="mode-select">
        <option v-for="m in modes" :key="m.value" :value="m.value">{{ m.label }}</option>
      </select>
      <button class="ms-fm-btn ms-fm-btn-primary" @click="search" :disabled="loading || !query">
        <span v-if="loading" class="spinner"></span>
        {{ loading ? 'Searching...' : 'Search' }}
      </button>
    </div>

    <div v-if="loading && !results.length" class="loading-state">
      <div class="spinner-lg"></div>
      <p>Searching...</p>
    </div>

    <div class="results" v-if="results.length">
      <div v-for="(r, i) in results" :key="i" class="result-card" @click="playVideo(r)">
        <div class="result-thumb">
          <img v-if="thumbs[r.file_uuid]" :src="thumbs[r.file_uuid]" alt="" loading="lazy" @vue:mounted="loadThumb(r.file_uuid)">
          <div v-else class="thumb-placeholder" @vue:mounted="loadThumb(r.file_uuid)">
            <div class="play-icon">▶</div>
          </div>
        </div>
        <div class="result-info">
          <div class="result-meta">
            <span class="score">{{ (r.similarity * 100).toFixed(0) }}%</span>
            <span class="time">{{ formatTime(r.start_time) }} - {{ formatTime(r.end_time) }}</span>
          </div>
          <p class="summary">{{ r.summary }}</p>
          <p class="file-name">{{ r.file_name }}</p>
        </div>
      </div>
    </div>
    <p v-else-if="searched" class="no-results">No results found</p>

    <VideoPlayer
      v-if="playing"
      :file-uuid="currentVideo.fileUuid"
      :start-time="currentVideo.startTime"
      :end-time="currentVideo.endTime"
      :title="currentVideo.title"
      @close="playing = false"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import VideoPlayer from '../components/VideoPlayer.vue'

const modes = [
  { label: 'Keyword', value: 'keyword' },
  { label: 'Semantic', value: 'semantic' }
]

const mode = ref('semantic')
const query = ref('')
const results = ref<any[]>([])
const loading = ref(false)
const searched = ref(false)
const thumbs = ref<Record<string, string>>({})

const playing = ref(false)
const currentVideo = ref({ fileUuid: '', startTime: 0, endTime: 0, title: '' })

async function search() {
  if (!query.value) return
  loading.value = true
  searched.value = false
  try {
    results.value = await invoke('search_llm_smart', { query: query.value, limit: 20 })
    searched.value = true
  } catch (e) {
    console.error('Search failed:', e)
    searched.value = true
  } finally {
    loading.value = false
  }
}

async function loadThumb(uuid: string) {
  if (!uuid || thumbs.value[uuid]) return
  try {
    thumbs.value[uuid] = await invoke('get_thumbnail', { uuid, frame: 30 })
  } catch {
    // keep placeholder
  }
}

function formatTime(sec: number): string {
  const m = Math.floor(sec / 60)
  const s = Math.floor(sec % 60)
  return `${m}:${s.toString().padStart(2, '0')}`
}

function playVideo(r: any) {
  currentVideo.value = {
    fileUuid: r.file_uuid,
    startTime: r.start_time,
    endTime: r.end_time,
    title: r.summary?.slice(0, 60) || r.file_name || 'Video'
  }
  playing.value = true
}
</script>

<style scoped>
.search-view { max-width: 900px; }
h1 { font-size: 1.5rem; margin-bottom: 24px; }
.search-bar { display: flex; gap: 10px; margin-bottom: 24px; }
.search-bar input { flex: 1; padding: 12px 16px; border: 1.5px solid #d1d5db; border-radius: 10px; font-size: 1rem; outline: none; transition: border-color 0.15s; }
.search-bar input:focus { border-color: #202124; }
.search-bar input:disabled { background: #f3f4f6; }
.mode-select { padding: 12px 16px; border: 1.5px solid #d1d5db; border-radius: 10px; font-size: 0.9rem; background: #fff; cursor: pointer; outline: none; }
.result-card { display: flex; gap: 16px; background: #fff; border: 1px solid #e8eaed; border-radius: 12px; padding: 16px; margin-bottom: 12px; cursor: pointer; transition: transform 0.15s, box-shadow 0.15s; }
.result-card:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,0.1); }
.result-thumb { width: 120px; height: 68px; border-radius: 8px; overflow: hidden; flex-shrink: 0; background: #e8eaed; }
.result-thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb-placeholder { width: 100%; height: 100%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; }
.play-icon { color: #fff; font-size: 1.5rem; opacity: 0.8; }
.result-info { flex: 1; min-width: 0; }
.result-meta { display: flex; gap: 12px; margin-bottom: 6px; }
.score { color: #1a56db; font-weight: 600; font-size: 0.85rem; }
.time { color: #9aa0a6; font-size: 0.85rem; }
.summary { color: #3c4043; margin-bottom: 4px; line-height: 1.4; }
.file-name { color: #9aa0a6; font-size: 0.8rem; }
.no-results { text-align: center; padding: 40px; color: #5f6368; }
.loading-state { text-align: center; padding: 60px 0; color: #5f6368; }
.spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-top-color: #fff; border-radius: 50%; animation: spin 0.6s linear infinite; margin-right: 6px; }
.spinner-lg { width: 24px; height: 24px; border: 3px solid #e8eaed; border-top-color: #202124; border-radius: 50%; animation: spin 0.7s linear infinite; margin: 0 auto 12px; }
@keyframes spin { to { transform: rotate(360deg); } }
</style>
