<template>
  <v-card>
    <v-card-title class="d-flex align-center" style="gap: 12px;">
      <span>Recent import tasks</span>
      <v-spacer />
      <v-select
        v-model="statusFilter" :items="statusOptions" density="compact"
        hide-details style="max-width: 180px;" @update:model-value="onFilterChange"
      />
      <v-btn variant="text" rounded="pill" size="small" @click="onRefresh">
        <v-icon start>mdi-refresh</v-icon>
        Refresh
      </v-btn>
      <v-btn
        variant="text" rounded="pill" size="small" color="warning"
        :disabled="!hasFailed" @click="onRetryFailed"
      >
        Retry failed
      </v-btn>
      <v-btn
        variant="text" rounded="pill" size="small" color="warning"
        :disabled="!hasStuck" @click="onClearStuckOpen"
      >
        Clear stuck…
      </v-btn>
      <v-btn
        variant="text" rounded="pill" size="small" color="error"
        @click="onClearOpen"
      >
        Clear completed…
      </v-btn>
    </v-card-title>
    <v-data-table-virtual
      :headers="headers" :items="store.tasks" :loading="store.tasksLoading"
      height="480" density="compact" no-data-text="No tasks yet — trigger a scan above."
    >
      <template #item.status="{ item }">
        <v-chip :color="statusColor(item.status)" size="small" variant="tonal">
          {{ item.status }}
        </v-chip>
      </template>
      <template #item.source_path="{ item }">
        <span :title="item.source_path">{{ shorten(item.source_path) }}</span>
      </template>
      <template #item.size_bytes="{ item }">{{ formatBytes(item.size_bytes) }}</template>
      <template #item.created_at="{ item }">{{ formatDate(item.created_at) }}</template>
      <template #item.error="{ item }">
        <span v-if="item.error" :title="item.error" class="text-caption">
          {{ shorten(item.error, 60) }}
        </span>
      </template>
    </v-data-table-virtual>
    <div v-if="store.hasMore" class="d-flex justify-center py-3">
      <v-btn variant="text" size="small" @click="onLoadMore">Load more</v-btn>
    </div>

    <v-dialog v-model="clearDialog" max-width="400">
      <v-card>
        <v-card-title>Clear completed tasks</v-card-title>
        <v-card-text>
          <v-select
            v-model="clearAgeDays" label="Older than"
            :items="[
              { title: 'All finished', value: 0 },
              { title: '1 day',  value: 1 },
              { title: '7 days', value: 7 },
              { title: '30 days', value: 30 }
            ]"
          />
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn @click="clearDialog = false">Cancel</v-btn>
          <v-btn color="error" rounded="pill" @click="onClearConfirm">Clear</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-dialog v-model="clearStuckDialog" max-width="480">
      <v-card>
        <v-card-title>Clear stuck tasks</v-card-title>
        <v-card-text>
          <v-alert type="warning" variant="tonal" density="compact" class="mb-3">
            Force every <strong>pending / queued / processing</strong> task to
            <strong>failed</strong> and finalize any active batch that
            has no remaining work. Use this when the automatic recovery
            sweep keeps re-queueing the same row (e.g., corrupt file in
            an autoretry loop, or worker model missing).
          </v-alert>
          <p class="text-body-2">
            Tasks remain in the database with status=<code>failed</code>;
            click <em>Retry failed</em> once the underlying cause is
            resolved to re-queue them.
          </p>
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn @click="clearStuckDialog = false">Cancel</v-btn>
          <v-btn color="warning" rounded="pill" @click="onClearStuckConfirm">Clear stuck</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </v-card>
</template>

<script setup>
import { computed, ref } from 'vue'
import { useImportStore } from '../../stores/import.js'

const store = useImportStore()
const statusFilter = ref(null)
const clearDialog = ref(false)
const clearAgeDays = ref(7)
const clearStuckDialog = ref(false)

const statusOptions = [
  { title: 'All', value: null },
  { title: 'Pending', value: 'pending' },
  { title: 'Queued', value: 'queued' },
  { title: 'Processing', value: 'processing' },
  { title: 'Complete', value: 'complete' },
  { title: 'Skipped', value: 'skipped' },
  { title: 'Failed', value: 'failed' }
]

const headers = [
  { title: 'Status', key: 'status', sortable: false, width: 120 },
  { title: 'Source', key: 'source_path', sortable: false },
  { title: 'Size', key: 'size_bytes', sortable: false, width: 90 },
  { title: 'Created', key: 'created_at', sortable: false, width: 150 },
  { title: 'Note', key: 'error', sortable: false }
]

const hasFailed = computed(() => store.tasks.some(t => t.status === 'failed'))
const hasStuck = computed(() => store.tasks.some(
  t => t.status === 'pending' || t.status === 'queued' || t.status === 'processing'
))

function statusColor(s) {
  return {
    complete: 'success',
    skipped: 'warning',
    failed: 'error',
    processing: 'accent',
    queued: 'info',
    pending: 'info'
  }[s] || 'default'
}
function shorten(s, max = 90) {
  if (!s) return ''
  if (s.length <= max) return s
  const head = Math.floor((max - 3) * 0.6)
  const tail = max - 3 - head
  return s.slice(0, head) + '...' + s.slice(-tail)
}
function formatBytes(b) {
  if (!b) return ''
  const units = ['B', 'KiB', 'MiB', 'GiB']
  let i = 0; let v = b
  while (v >= 1024 && i < units.length - 1) { v /= 1024; i++ }
  return `${v.toFixed(i === 0 ? 0 : 1)} ${units[i]}`
}
function formatDate(s) {
  try { return new Date(s).toLocaleString() } catch { return s }
}

async function onRefresh() { await store.loadTasks(true) }
function onFilterChange() { store.setStatusFilter(statusFilter.value); store.loadTasks(true) }
async function onLoadMore() { await store.loadTasks(false) }
async function onRetryFailed() { await store.retryFailed() }
function onClearOpen() { clearDialog.value = true }
async function onClearConfirm() {
  await store.clearCompleted(clearAgeDays.value)
  clearDialog.value = false
}
function onClearStuckOpen() { clearStuckDialog.value = true }
async function onClearStuckConfirm() {
  await store.clearStuck()
  clearStuckDialog.value = false
}
</script>
