<template>
  <div class="space-y-6">
    <div class="flex justify-between items-center">
      <h2 class="text-2xl font-bold">Face Traces</h2>
      <button
        @click="loadTraces"
        class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition"
      >
        Refresh
      </button>
    </div>

    <div class="bg-gray-800 rounded-lg p-4 border border-gray-700 space-y-4">
      <div class="grid grid-cols-4 gap-4">
        <div>
          <label class="text-gray-400 text-sm mb-1">Filter by File (必選)</label>
          <select
            v-model="selectedFileUuid"
            @change="loadTraces"
            class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-white"
          >
            <option value="">-- 選擇檔案 --</option>
            <option v-for="f in files" :key="f.file_uuid" :value="f.file_uuid">
              {{ f.file_name?.substring(0, 50) || f.file_uuid }}
            </option>
          </select>
        </div>
        <div>
          <label class="text-gray-400 text-sm mb-1">Sort By</label>
          <select
            v-model="sortBy"
            @change="loadTraces"
            class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-white"
          >
            <option value="face_count">Face Count</option>
            <option value="duration">Duration</option>
            <option value="first_appearance">First Appearance</option>
          </select>
        </div>
        <div>
          <label class="text-gray-400 text-sm mb-1">Min Faces</label>
          <input
            v-model.number="minFaces"
            @change="loadTraces"
            type="number"
            min="1"
            max="1000"
            class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-white"
          />
        </div>
        <div>
          <label class="text-gray-400 text-sm mb-1">Binding Status</label>
          <select
            v-model="bindingFilter"
            @change="loadTraces"
            class="w-full bg-gray-700 border border-gray-600 rounded px-3 py-2 text-white"
          >
            <option value="all">全部</option>
            <option value="registered">已綁定</option>
            <option value="unregistered">未綁定</option>
          </select>
        </div>
      </div>
    </div>

    <div v-if="!selectedFileUuid" class="text-center py-12 text-gray-500">
      請選擇一個檔案來檢視 Face Traces
    </div>

    <template v-else>
      <div v-if="loading && traces.length === 0" class="text-center py-12 text-gray-500">
        <div class="animate-spin rounded-full h-10 w-10 border-b-2 border-blue-500 mx-auto mb-4"></div>
        <span>Loading...</span>
      </div>

      <div v-if="traces.length > 0">
        <div class="bg-gray-800 rounded-lg p-4 border border-gray-700 mb-4 flex justify-between items-center">
          <div class="text-gray-400">
            Showing {{ paginatedTraces.length }} of {{ traces.length }} traces
          </div>
          <div class="flex items-center space-x-2">
            <span class="text-xs text-gray-500">每頁</span>
            <select v-model.number="pageSize" @change="page=1"
              class="bg-gray-700 border border-gray-600 rounded px-2 py-1 text-white text-xs">
              <option :value="20">20</option>
              <option :value="50">50</option>
              <option :value="100">100</option>
            </select>
          </div>
        </div>

        <!-- Pagination top -->
        <div v-if="totalPages > 1" class="flex justify-center mb-4 space-x-2">
          <button @click="page = 1" :disabled="page === 1"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">«</button>
          <button @click="page--" :disabled="page === 1"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">‹</button>
          <span class="text-gray-400 text-sm py-1">{{ page }} / {{ totalPages }}</span>
          <button @click="page++" :disabled="page >= totalPages"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">›</button>
          <button @click="page = totalPages" :disabled="page >= totalPages"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">»</button>
        </div>

        <!-- Loading overlay during pagination -->
        <div v-if="loading" class="text-center py-4 text-gray-500 mb-2">
          <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto"></div>
        </div>

        <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
          <div
            v-for="trace in paginatedTraces"
            :key="trace.trace_id"
            @click="viewTrace(trace)"
            class="bg-gray-800 rounded-lg border border-gray-700 overflow-hidden cursor-pointer hover:border-blue-500 transition"
          >
            <div class="aspect-square bg-gray-700 flex items-center justify-center overflow-hidden">
              <img
                :src="getThumbnailUrl(trace)"
                alt="Trace thumbnail"
                class="w-full h-full object-cover"
                loading="lazy"
                @error="onThumbnailError(trace.trace_id)"
              />
            </div>
            <div class="p-3 space-y-1">
              <div class="flex items-center justify-between">
                <div class="text-sm font-semibold text-blue-300">Trace #{{ trace.trace_id }}</div>
                <span class="text-xs px-1.5 py-0.5 rounded"
                  :class="trace.face_count > 5 ? 'bg-green-900 text-green-300' : 'bg-gray-700 text-gray-400'">
                  {{ trace.face_count > 5 ? '多' : '少' }}
                </span>
              </div>
              <div class="text-xs text-gray-400">{{ trace.face_count }} faces, {{ trace.duration_sec?.toFixed(1) || '?' }}s</div>
              <div class="text-xs font-mono" :class="getConfidenceColor(trace.avg_confidence)">
                {{ (trace.avg_confidence * 100).toFixed(0) }}%
              </div>
            </div>
          </div>
        </div>

        <!-- Pagination bottom -->
        <div v-if="totalPages > 1" class="flex justify-center mt-6 space-x-2">
          <button @click="page = 1" :disabled="page === 1"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">«</button>
          <button @click="page--" :disabled="page === 1"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">‹</button>
          <span class="text-gray-400 text-sm py-1">{{ page }} / {{ totalPages }}</span>
          <button @click="page++" :disabled="page >= totalPages"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">›</button>
          <button @click="page = totalPages" :disabled="page >= totalPages"
            class="bg-gray-700 hover:bg-gray-600 disabled:opacity-50 px-3 py-1 rounded text-sm">»</button>
        </div>
      </div>

      <div v-if="!loading && traces.length === 0" class="text-center py-12 text-gray-500">
        No traces found for this file
      </div>
    </template>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { getVideos, getCurrentConfig } from '@/api/client'

const router = useRouter()

interface TraceInfo {
  trace_id: number
  face_count: number
  first_frame: number
  last_frame: number
  first_sec: number
  last_sec: number
  duration_sec: number
  avg_confidence: number
  sample_face_id?: string | null
}

const traces = ref<TraceInfo[]>([])
const loading = ref(false)
const totalTraces = ref(0)
const selectedFileUuid = ref('')
const files = ref<any[]>([])
const sortBy = ref('face_count')
const minFaces = ref(1)
const bindingFilter = ref('all')
const page = ref(1)
const pageSize = ref(50)

const totalPages = computed(() => Math.max(1, Math.ceil(traces.value.length / pageSize.value)))

const paginatedTraces = computed(() => {
  const start = (page.value - 1) * pageSize.value
  return traces.value.slice(start, start + pageSize.value)
})

const failedThumbnails = ref<Set<number>>(new Set())

const getThumbnailUrl = (trace: TraceInfo): string => {
  const config = getCurrentConfig()
  return `${config.api_base_url}/api/v1/file/${selectedFileUuid.value}/thumbnail?frame=${trace.first_frame}`
}

const onThumbnailError = (traceId: number) => {
  failedThumbnails.value = new Set([...failedThumbnails.value, traceId])
}

const getConfidenceColor = (conf: number): string => {
  if (conf >= 0.8) return 'text-green-400'
  if (conf >= 0.5) return 'text-yellow-400'
  return 'text-red-400'
}

const viewTrace = (trace: TraceInfo) => {
  router.push(`/traces/${selectedFileUuid.value}/${trace.trace_id}`)
}

const loadTraces = async () => {
  if (!selectedFileUuid.value) return
  loading.value = true
  page.value = 1
  try {
    const config = getCurrentConfig()
    const result = await fetch(
      `${config.api_base_url}/api/v1/file/${selectedFileUuid.value}/face_trace/sortby`,
      {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(config.api_key ? { 'X-API-Key': config.api_key } : {})
        },
        body: JSON.stringify({
          sort_by: sortBy.value,
          limit: 200,
          min_faces: minFaces.value
        })
      }
    )
    const data = await result.json()
    traces.value = data.traces || []
    totalTraces.value = data.total_traces || 0
  } catch (e) {
    console.error('Failed to load traces:', e)
  } finally {
    loading.value = false
  }
}

onMounted(async () => {
  try {
    const result = await getVideos()
    files.value = result.data || result.files || []
  } catch { /* ignore */ }
})
</script>