<template>
  <div>
    <!-- Header with Stats and Actions -->
    <v-row class="mb-4" align="center">
      <v-col cols="12" md="6">
        <h1 class="text-h5 mb-2">Downloads</h1>
        <div v-if="downloadsStore.stats" class="d-flex flex-wrap ga-2">
          <v-chip color="warning" variant="tonal" size="small">
            <v-icon start size="small">mdi-clock-outline</v-icon>
            {{ downloadsStore.stats.queued || 0 }} Queued
          </v-chip>
          <v-chip color="info" variant="tonal" size="small">
            <v-icon start size="small" class="mdi-spin">mdi-loading</v-icon>
            {{ downloadsStore.stats.running || 0 }} Running
          </v-chip>
          <v-chip color="success" variant="tonal" size="small">
            <v-icon start size="small">mdi-check-circle</v-icon>
            {{ downloadsStore.stats.completed || 0 }} Completed
          </v-chip>
          <v-chip color="error" variant="tonal" size="small">
            <v-icon start size="small">mdi-alert-circle</v-icon>
            {{ downloadsStore.stats.failed || 0 }} Failed
          </v-chip>
        </div>
      </v-col>
      <v-col cols="12" md="6" class="d-flex justify-end ga-2 flex-wrap">
        <v-btn
          variant="outlined"
          size="small"
          @click="refresh"
          :loading="downloadsStore.loading"
        >
          <v-icon start>mdi-refresh</v-icon>
          Refresh
        </v-btn>
        <v-menu>
          <template v-slot:activator="{ props }">
            <v-btn
              variant="outlined"
              size="small"
              color="warning"
              v-bind="props"
            >
              <v-icon start>mdi-wrench</v-icon>
              Maintenance
              <v-icon end>mdi-chevron-down</v-icon>
            </v-btn>
          </template>
          <v-list density="compact">
            <v-list-item @click="resetOrphanedJobs">
              <v-list-item-title>Reset Orphaned Running Jobs</v-list-item-title>
              <v-list-item-subtitle>Reset jobs stuck in "running" status</v-list-item-subtitle>
            </v-list-item>
            <v-list-item @click="requeueStaleJobs">
              <v-list-item-title>Re-queue Stale Queued Jobs</v-list-item-title>
              <v-list-item-subtitle>Re-send lost Celery tasks for queued jobs</v-list-item-subtitle>
            </v-list-item>
            <v-divider />
            <v-list-item @click="exportFailedLogs">
              <v-list-item-title>
                <v-icon start size="small">mdi-download</v-icon>
                Export Failed Logs
              </v-list-item-title>
              <v-list-item-subtitle>Download JSON for error analysis</v-list-item-subtitle>
            </v-list-item>
          </v-list>
        </v-menu>
      </v-col>
    </v-row>

    <!-- Filters -->
    <v-row class="mb-4">
      <v-col cols="12" md="3">
        <v-select
          v-model="filterStatus"
          :items="statusOptions"
          label="Status"
          density="compact"
          variant="outlined"
          clearable
        />
      </v-col>
      <v-col cols="12" md="3">
        <v-select
          v-model="filterSourceId"
          :items="sourceOptions"
          label="Source"
          density="compact"
          variant="outlined"
          clearable
        />
      </v-col>
      <v-col cols="12" md="3">
        <v-text-field
          v-model="filterFromDate"
          label="From Date"
          type="date"
          density="compact"
          variant="outlined"
          clearable
        />
      </v-col>
      <v-col cols="12" md="3">
        <v-text-field
          v-model="filterToDate"
          label="To Date"
          type="date"
          density="compact"
          variant="outlined"
          clearable
        />
      </v-col>
    </v-row>

    <!-- Superseded filter -->
    <v-row class="mb-4">
      <v-col cols="12">
        <v-switch
          v-model="filterExcludeSuperseded"
          label="Hide superseded failures"
          density="compact"
          hide-details
          color="primary"
        />
      </v-col>
    </v-row>

    <!-- Downloads Table -->
    <v-card>
      <v-data-table
        :headers="headers"
        :items="downloadsStore.downloads"
        :loading="downloadsStore.loading"
        :items-per-page="20"
        class="elevation-1"
      >
        <template v-slot:item.status="{ item }">
          <v-chip
            :color="getStatusColor(item.status)"
            size="small"
            variant="tonal"
          >
            <v-icon start size="small" :class="{ 'mdi-spin': item.status === 'running' }">
              {{ getStatusIcon(item.status) }}
            </v-icon>
            {{ item.status }}
          </v-chip>
        </template>

        <template v-slot:item.source="{ item }">
          <span class="text-caption">{{ getSourceLabel(item.source_id) }}</span>
        </template>

        <template v-slot:item.url="{ item }">
          <span :title="item.url" class="text-caption">{{ truncateUrl(item.url) }}</span>
        </template>

        <template v-slot:item.error_type="{ item }">
          <v-chip
            v-if="item.error_type"
            color="error"
            size="small"
            variant="tonal"
          >
            {{ formatErrorType(item.error_type) }}
          </v-chip>
          <span v-else class="text-grey">-</span>
        </template>

        <template v-slot:item.file_count="{ item }">
          <v-chip v-if="item.file_count > 0" color="success" size="small">
            {{ item.file_count }} files
          </v-chip>
          <span v-else class="text-grey">0</span>
        </template>

        <template v-slot:item.created_at="{ item }">
          {{ formatDate(item.created_at) }}
        </template>

        <template v-slot:item.duration="{ item }">
          {{ formatDuration(item) }}
        </template>

        <template v-slot:item.actions="{ item }">
          <v-btn
            v-if="item.status === 'failed'"
            icon
            size="small"
            variant="text"
            color="primary"
            @click="retryDownload(item)"
            :loading="retryingIds.includes(item.id)"
          >
            <v-icon>mdi-refresh</v-icon>
            <v-tooltip activator="parent">Retry</v-tooltip>
          </v-btn>
          <v-btn
            icon
            size="small"
            variant="text"
            @click="showDetails(item)"
          >
            <v-icon>mdi-information</v-icon>
            <v-tooltip activator="parent">Details</v-tooltip>
          </v-btn>
        </template>

        <template v-slot:no-data>
          <div class="text-center pa-4">
            <v-icon size="48" color="grey-lighten-1">mdi-download-off</v-icon>
            <p class="text-grey mt-2">No downloads found</p>
          </div>
        </template>
      </v-data-table>
    </v-card>

    <!-- Details Dialog -->
    <v-dialog v-model="detailsDialog" max-width="700">
      <v-card v-if="selectedDownload">
        <v-card-title>
          Download Details
          <v-chip
            :color="getStatusColor(selectedDownload.status)"
            size="small"
            class="ml-2"
          >
            {{ selectedDownload.status }}
          </v-chip>
        </v-card-title>

        <v-card-text>
          <v-table density="compact">
            <tbody>
              <tr>
                <td class="font-weight-bold" width="150">Source</td>
                <td>{{ getSourceLabel(selectedDownload.source_id) }}</td>
              </tr>
              <tr>
                <td class="font-weight-bold">URL</td>
                <td style="word-break: break-all">{{ selectedDownload.url }}</td>
              </tr>
              <tr>
                <td class="font-weight-bold">Files Downloaded</td>
                <td>{{ selectedDownload.file_count }}</td>
              </tr>
              <tr>
                <td class="font-weight-bold">Created</td>
                <td>{{ formatDate(selectedDownload.created_at) }}</td>
              </tr>
              <tr>
                <td class="font-weight-bold">Started</td>
                <td>{{ formatDate(selectedDownload.started_at) }}</td>
              </tr>
              <tr>
                <td class="font-weight-bold">Completed</td>
                <td>{{ formatDate(selectedDownload.completed_at) }}</td>
              </tr>
              <tr v-if="selectedDownload.error_type">
                <td class="font-weight-bold">Error Type</td>
                <td class="text-error">{{ formatErrorType(selectedDownload.error_type) }}</td>
              </tr>
              <tr v-if="selectedDownload.error_message">
                <td class="font-weight-bold">Error Message</td>
                <td class="text-error">{{ selectedDownload.error_message }}</td>
              </tr>
            </tbody>
          </v-table>

          <v-expansion-panels class="mt-4" v-if="selectedDownload.metadata">
            <v-expansion-panel v-if="selectedDownload.metadata.stdout">
              <v-expansion-panel-title>Output Log</v-expansion-panel-title>
              <v-expansion-panel-text>
                <pre class="text-caption" style="white-space: pre-wrap; max-height: 300px; overflow: auto">{{ selectedDownload.metadata.stdout }}</pre>
              </v-expansion-panel-text>
            </v-expansion-panel>
            <v-expansion-panel v-if="selectedDownload.metadata.stderr">
              <v-expansion-panel-title>Error Log</v-expansion-panel-title>
              <v-expansion-panel-text>
                <pre class="text-caption text-error" style="white-space: pre-wrap; max-height: 300px; overflow: auto">{{ selectedDownload.metadata.stderr }}</pre>
              </v-expansion-panel-text>
            </v-expansion-panel>
          </v-expansion-panels>
        </v-card-text>

        <v-card-actions>
          <v-spacer />
          <v-btn
            v-if="selectedDownload.status === 'failed'"
            color="primary"
            @click="retryDownload(selectedDownload); detailsDialog = false"
          >
            Retry Download
          </v-btn>
          <v-btn variant="text" @click="detailsDialog = false">Close</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useDownloadsStore } from '../stores/downloads'
import { useSourcesStore } from '../stores/sources'
import { useNotificationStore } from '../stores/notifications'

const downloadsStore = useDownloadsStore()
const sourcesStore = useSourcesStore()
const notifications = useNotificationStore()

const filterStatus = ref(null)
const filterSourceId = ref(null)
const filterFromDate = ref(null)
const filterToDate = ref(null)
const filterExcludeSuperseded = ref(true)
const detailsDialog = ref(false)
const selectedDownload = ref(null)
const retryingIds = ref([])
let refreshInterval = null

const statusOptions = [
  { title: 'Queued', value: 'queued' },
  { title: 'Running', value: 'running' },
  { title: 'Completed', value: 'completed' },
  { title: 'Failed', value: 'failed' },
  { title: 'Skipped', value: 'skipped' },
]

const sourceOptions = computed(() =>
  sourcesStore.sources.map(s => ({
    title: `${s.subscription_name || 'Unknown'}:${s.platform}`,
    value: s.id
  }))
)

const headers = [
  { title: 'Status', key: 'status', width: 120 },
  { title: 'Source', key: 'source', width: 180 },
  { title: 'URL', key: 'url' },
  { title: 'Error', key: 'error_type', width: 130 },
  { title: 'Files', key: 'file_count', width: 80 },
  { title: 'Date', key: 'created_at', width: 160 },
  { title: 'Duration', key: 'duration', width: 90 },
  { title: 'Actions', key: 'actions', width: 90, sortable: false },
]

onMounted(() => {
  refresh()
  sourcesStore.fetchSources()

  // Auto-refresh every 30 seconds if there are running/queued jobs
  refreshInterval = setInterval(() => {
    if (downloadsStore.stats?.running > 0 || downloadsStore.stats?.queued > 0) {
      loadDownloads()
      downloadsStore.fetchStats()
    }
  }, 30000)
})

onUnmounted(() => {
  if (refreshInterval) {
    clearInterval(refreshInterval)
  }
})

watch([filterStatus, filterSourceId, filterFromDate, filterToDate, filterExcludeSuperseded], () => {
  loadDownloads()
})

async function refresh() {
  await Promise.all([
    loadDownloads(),
    downloadsStore.fetchStats()
  ])
}

async function loadDownloads() {
  const params = {}
  if (filterStatus.value) params.status = filterStatus.value
  if (filterSourceId.value) params.source_id = filterSourceId.value
  if (filterFromDate.value) params.from_date = filterFromDate.value
  if (filterToDate.value) params.to_date = filterToDate.value
  if (filterExcludeSuperseded.value) params.exclude_superseded = true
  await downloadsStore.fetchDownloads(params)
}

async function resetOrphanedJobs() {
  try {
    const result = await downloadsStore.resetOrphaned()
    notifications.success(`Reset ${result.data.reset_count} orphaned jobs`)
    await refresh()
  } catch (error) {
    notifications.error(`Failed to reset orphaned jobs: ${error.message}`)
  }
}

async function requeueStaleJobs() {
  try {
    const result = await downloadsStore.requeueStale()
    notifications.success(`Re-queued ${result.data.requeued_count} stale jobs`)
    await refresh()
  } catch (error) {
    notifications.error(`Failed to re-queue stale jobs: ${error.message}`)
  }
}

async function exportFailedLogs() {
  try {
    // Open download in new tab - the API returns a file attachment
    const baseUrl = import.meta.env.VITE_API_URL || '/api'
    const url = `${baseUrl}/downloads/export-failed-logs?limit=100&days=30&include_success=true`
    window.open(url, '_blank')
    notifications.success('Exporting failed logs...')
  } catch (error) {
    notifications.error(`Failed to export logs: ${error.message}`)
  }
}

function getStatusIcon(status) {
  const icons = {
    completed: 'mdi-check-circle',
    failed: 'mdi-alert-circle',
    running: 'mdi-loading',
    queued: 'mdi-clock-outline',
    skipped: 'mdi-skip-next',
  }
  return icons[status] || 'mdi-help-circle'
}

function getStatusColor(status) {
  const colors = {
    completed: 'success',
    failed: 'error',
    running: 'info',
    queued: 'warning',
    skipped: 'grey',
  }
  return colors[status] || 'grey'
}

function formatDate(dateStr) {
  if (!dateStr) return '-'
  return new Date(dateStr).toLocaleString()
}

function formatDuration(download) {
  if (!download.started_at || !download.completed_at) return '-'
  const start = new Date(download.started_at)
  const end = new Date(download.completed_at)
  const seconds = Math.round((end - start) / 1000)
  if (seconds < 60) return `${seconds}s`
  const minutes = Math.floor(seconds / 60)
  return `${minutes}m ${seconds % 60}s`
}

function formatErrorType(errorType) {
  if (!errorType) return ''
  return errorType.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())
}

function truncateUrl(url) {
  if (!url) return ''
  if (url.length <= 40) return url
  return url.substring(0, 37) + '...'
}

function getSourceLabel(sourceId) {
  if (!sourceId) return 'N/A'
  const source = sourcesStore.sources.find(s => s.id === sourceId)
  if (source) {
    return `${source.subscription_name || 'Unknown'}:${source.platform}`
  }
  return `Source #${sourceId}`
}

function showDetails(download) {
  selectedDownload.value = download
  detailsDialog.value = true
}

async function retryDownload(download) {
  retryingIds.value.push(download.id)
  try {
    await downloadsStore.retryDownload(download.id)
    notifications.success('Download queued for retry')
    await refresh()
  } catch (error) {
    notifications.error(`Failed to retry: ${error.message}`)
  } finally {
    retryingIds.value = retryingIds.value.filter(id => id !== download.id)
  }
}
</script>

<style scoped>
.mdi-spin {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
</style>
