<template>
  <div class="space-y-4 max-w-4xl">
    <!-- Status banner -->
    <UAlert
      v-if="status.running"
      icon="i-heroicons-radio"
      color="green"
      variant="soft"
      :title="`Захват активен — ${status.source} (${modeLabel(status.mode)})`"
      :description="`Пакетов: ${status.pkts?.toLocaleString() ?? 0} · Трафик: ${humanBytes(status.bytes ?? 0)}`"
    >
      <template #actions>
        <UButton color="red" variant="soft" size="xs" @click="doStop">Остановить</UButton>
      </template>
    </UAlert>

    <!-- Tabs: Live / PCAP -->
    <UCard :ui="cardUi">
      <template #header>
        <p class="text-sm font-semibold text-gray-200">Источник трафика</p>
      </template>

      <UTabs :items="tabs" :ui="tabsUi">
        <!-- Live capture tab -->
        <template #live>
          <div class="space-y-4 pt-4">
            <div>
              <label class="text-xs text-gray-400 mb-1.5 block">Сетевой интерфейс</label>
              <div class="flex gap-2">
                <USelect
                  v-model="liveIface"
                  :options="ifaceOptions"
                  :disabled="status.running"
                  class="flex-1"
                  :ui="selectUi"
                />
                <UButton
                  color="gray"
                  variant="soft"
                  size="sm"
                  icon="i-heroicons-arrow-path"
                  :loading="loadingIfaces"
                  @click="loadInterfaces"
                />
              </div>
            </div>

            <UAlert
              icon="i-heroicons-information-circle"
              color="blue"
              variant="soft"
              title="Требуются права суперпользователя"
              description="Live-захват использует raw sockets. Запустите бэкенд через sudo."
            />

            <UButton
              :color="status.running ? 'red' : 'green'"
              :icon="status.running ? 'i-heroicons-stop-circle' : 'i-heroicons-play-circle'"
              :loading="actionLoading"
              size="sm"
              @click="status.running ? doStop() : doStartLive()"
            >
              {{ status.running ? 'Остановить захват' : 'Начать захват' }}
            </UButton>
          </div>
        </template>

        <!-- PCAP upload tab -->
        <template #pcap>
          <div class="space-y-4 pt-4">
            <div
              class="border-2 border-dashed border-gray-700 rounded-xl p-8 text-center transition-colors"
              :class="dragging ? 'border-blue-500 bg-blue-500/5' : 'hover:border-gray-600'"
              @dragover.prevent="dragging = true"
              @dragleave="dragging = false"
              @drop.prevent="onDrop"
            >
              <UIcon name="i-heroicons-document-arrow-up" class="w-10 h-10 text-gray-600 mx-auto mb-3" />
              <p class="text-sm text-gray-400 mb-1">
                {{ pcapFile ? pcapFile.name : 'Перетащите .pcap файл или выберите' }}
              </p>
              <p class="text-xs text-gray-600 mb-3">Поддерживается формат libpcap / pcapng</p>
              <label class="cursor-pointer">
                <UButton color="gray" variant="soft" size="sm" as="span">
                  Выбрать файл
                </UButton>
                <input type="file" accept=".pcap,.pcapng" class="hidden" @change="onFileSelect" />
              </label>
            </div>

            <UButton
              color="blue"
              icon="i-heroicons-arrow-up-tray"
              :disabled="!pcapFile || status.running"
              :loading="actionLoading"
              size="sm"
              @click="doUploadPCAP"
            >
              {{ pcapFile ? `Анализировать ${pcapFile.name}` : 'Выберите файл' }}
            </UButton>
          </div>
        </template>
      </UTabs>
    </UCard>

    <!-- Sessions history -->
    <UCard :ui="cardUi">
      <template #header>
        <p class="text-sm font-semibold text-gray-200">История сессий</p>
      </template>

      <UTable :rows="sessions" :columns="sessionColumns" :ui="tableUi">
        <template #mode-data="{ row }">
          <UBadge :color="row.mode === 'live' ? 'blue' : 'purple'" variant="soft" size="xs">
            {{ modeLabel(row.mode) }}
          </UBadge>
        </template>
        <template #status-data="{ row }">
          <UBadge :color="row.status === 'running' ? 'green' : 'gray'" variant="soft" size="xs">
            {{ statusLabel(row.status) }}
          </UBadge>
        </template>
        <template #total_pkts-data="{ row }">
          <span class="text-xs font-mono">{{ row.total_pkts.toLocaleString() }}</span>
        </template>
        <template #total_bytes-data="{ row }">
          <span class="text-xs font-mono">{{ humanBytes(row.total_bytes) }}</span>
        </template>
        <template #created_at-data="{ row }">
          <span class="text-xs text-gray-400">{{ formatTime(row.created_at) }}</span>
        </template>
      </UTable>
    </UCard>
  </div>
</template>

<script setup lang="ts">
const { post, upload, get } = useApi()
const { status, fetchStatus, stopCapture } = useCaptureStatus()

const liveIface    = ref('')
const pcapFile     = ref<File | null>(null)
const dragging     = ref(false)
const actionLoading = ref(false)
const loadingIfaces = ref(false)
const sessions     = ref<any[]>([])
const ifaceOptions = ref<{ label: string, value: string }[]>([])

const tabs = [
  { slot: 'live', label: 'Live захват', icon: 'i-heroicons-radio' },
  { slot: 'pcap', label: 'PCAP файл',   icon: 'i-heroicons-document' },
]

const sessionColumns = [
  { key: 'created_at',  label: 'Время' },
  { key: 'source',      label: 'Источник' },
  { key: 'mode',        label: 'Режим' },
  { key: 'status',      label: 'Статус' },
  { key: 'total_pkts',  label: 'Пакетов' },
  { key: 'total_bytes', label: 'Трафик' },
]

async function loadInterfaces() {
  loadingIfaces.value = true
  try {
    const res = await get<any>('/capture/interfaces')
    ifaceOptions.value = (res.interfaces ?? []).map((i: string) => ({ label: i, value: i }))
    if (!liveIface.value && ifaceOptions.value.length) {
      liveIface.value = ifaceOptions.value[0].value
    }
  } finally {
    loadingIfaces.value = false
  }
}

async function loadSessions() {
  const res = await get<any>('/capture/sessions')
  sessions.value = res.data ?? []
}

async function doStartLive() {
  actionLoading.value = true
  try {
    await post('/capture/start', { interface: liveIface.value })
    await fetchStatus()
    await loadSessions()
  } finally {
    actionLoading.value = false
  }
}

async function doStop() {
  actionLoading.value = true
  try {
    await stopCapture()
    await loadSessions()
  } finally {
    actionLoading.value = false
  }
}

async function doUploadPCAP() {
  if (!pcapFile.value) return
  actionLoading.value = true
  try {
    await upload('/capture/upload', pcapFile.value)
    await fetchStatus()
    await loadSessions()
    pcapFile.value = null
  } finally {
    actionLoading.value = false
  }
}

function onFileSelect(e: Event) {
  const input = e.target as HTMLInputElement
  if (input.files?.[0]) pcapFile.value = input.files[0]
}

function onDrop(e: DragEvent) {
  dragging.value = false
  const file = e.dataTransfer?.files[0]
  if (file) pcapFile.value = file
}

function modeLabel(m?: string) {
  return m === 'live' ? 'Live' : m === 'pcap' ? 'PCAP' : m ?? ''
}

function statusLabel(s: string) {
  return ({ running: 'Активна', stopped: 'Остановлена', completed: 'Завершена' } as any)[s] ?? s
}

function humanBytes(b: number) {
  if (b >= 1 << 30) return `${(b / (1 << 30)).toFixed(2)} GB`
  if (b >= 1 << 20) return `${(b / (1 << 20)).toFixed(2)} MB`
  if (b >= 1 << 10) return `${(b / (1 << 10)).toFixed(2)} KB`
  return `${b} B`
}

function formatTime(iso: string) {
  return new Date(iso).toLocaleString('ru-RU', { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit' })
}

onMounted(() => { loadInterfaces(); loadSessions() })

const cardUi  = { base: 'bg-gray-900 border border-gray-800', header: { base: 'border-b border-gray-800 px-4 py-3' }, body: { base: 'px-4 py-4' } }
const tableUi = { wrapper: 'overflow-x-auto', td: { base: 'py-2' }, th: { base: 'text-gray-400 text-xs font-medium' } }
const selectUi = { base: 'bg-gray-800 border-gray-700 text-gray-200' }
const tabsUi   = { list: { background: 'bg-gray-800', tab: { active: 'bg-gray-700' } } }
</script>
