<template>
  <div>
    <v-row>
      <!-- Stats Cards -->
      <v-col cols="12" md="3">
        <v-card>
          <v-card-text class="d-flex align-center">
            <v-avatar color="primary" size="48" class="mr-4">
              <v-icon>mdi-account-multiple</v-icon>
            </v-avatar>
            <div>
              <div class="text-h4">{{ sourcesStore.sources.length }}</div>
              <div class="text-caption">Total Sources</div>
            </div>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col cols="12" md="3">
        <v-card>
          <v-card-text class="d-flex align-center">
            <v-avatar color="success" size="48" class="mr-4">
              <v-icon>mdi-check-circle</v-icon>
            </v-avatar>
            <div>
              <div class="text-h4">{{ stats?.completed || 0 }}</div>
              <div class="text-caption">Completed Downloads</div>
            </div>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col cols="12" md="3">
        <v-card>
          <v-card-text class="d-flex align-center">
            <v-avatar color="error" size="48" class="mr-4">
              <v-icon>mdi-alert-circle</v-icon>
            </v-avatar>
            <div>
              <div class="text-h4">{{ stats?.active_failed || 0 }}</div>
              <div class="text-caption">Failed Downloads</div>
            </div>
          </v-card-text>
        </v-card>
      </v-col>

      <v-col cols="12" md="3">
        <v-card>
          <v-card-text class="d-flex align-center">
            <v-avatar color="warning" size="48" class="mr-4">
              <v-icon>mdi-clock-outline</v-icon>
            </v-avatar>
            <div>
              <div class="text-h4">{{ activeDownloadsCount }}</div>
              <div class="text-caption">Active Downloads</div>
              <div class="text-caption text-grey" v-if="stats?.queued || stats?.running">
                {{ stats?.queued || 0 }} queued, {{ stats?.running || 0 }} running
              </div>
            </div>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>

    <!-- Quick Actions -->
    <v-row class="mt-4">
      <v-col cols="12">
        <v-card>
          <v-card-text class="d-flex align-center ga-4 flex-wrap">
            <v-btn
              color="primary"
              prepend-icon="mdi-refresh"
              :loading="checkingAll"
              @click="checkAllSources"
            >
              Check All Sources
            </v-btn>
            <v-btn
              color="warning"
              prepend-icon="mdi-replay"
              :loading="retryingAll"
              :disabled="!failedCount"
              @click="retryAllFailed"
            >
              Retry All Failed ({{ failedCount }})
            </v-btn>
            <v-btn
              color="secondary"
              variant="outlined"
              prepend-icon="mdi-broom"
              :loading="resettingOrphaned"
              :disabled="!stuckRunningCount"
              @click="resetOrphanedJobs"
            >
              Reset Stuck ({{ stuckRunningCount }})
            </v-btn>
            <v-spacer />
            <!-- Credential Status -->
            <div class="d-flex align-center ga-2">
              <v-icon size="small" class="mr-1">mdi-key</v-icon>
              <span class="text-body-2 text-grey mr-2">Auth:</span>
              <v-chip
                v-for="platform in supportedPlatforms"
                :key="platform"
                :color="credentialsStore.hasPlatformCredentials(platform) ? 'success' : 'grey'"
                :variant="credentialsStore.hasPlatformCredentials(platform) ? 'tonal' : 'outlined'"
                size="x-small"
                :to="credentialsStore.hasPlatformCredentials(platform) ? undefined : '/credentials'"
              >
                <v-icon start size="x-small">{{ getPlatformIcon(platform) }}</v-icon>
                {{ platform }}
              </v-chip>
            </div>
            <v-divider vertical class="mx-2" />
            <div class="text-body-2 text-grey d-flex align-center">
              <v-icon size="small" class="mr-1">mdi-harddisk</v-icon>
              Storage: {{ storageStats?.total_size_formatted || 'Calculating...' }}
              <span v-if="storageStats?.file_count" class="ml-2">
                ({{ storageStats.file_count.toLocaleString() }} files)
              </span>
              <v-tooltip v-if="storageStats?.calculated_at" location="bottom">
                <template v-slot:activator="{ props }">
                  <v-icon v-bind="props" size="x-small" class="ml-2">mdi-information-outline</v-icon>
                </template>
                <span>Updated: {{ formatDate(storageStats.calculated_at) }}</span>
              </v-tooltip>
              <v-btn
                icon
                size="x-small"
                variant="text"
                class="ml-1"
                :loading="refreshingStorage"
                @click="refreshStorageStats"
                title="Refresh storage stats"
              >
                <v-icon size="small">mdi-refresh</v-icon>
              </v-btn>
            </div>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>

    <v-row class="mt-4">
      <!-- Active Downloads (queued + running, auto-refresh) -->
      <v-col cols="12" md="4">
        <v-card>
          <v-card-title class="d-flex align-center">
            <v-icon class="mr-2" :class="{ 'mdi-spin': activeDownloads.length }">
              {{ activeDownloads.length ? 'mdi-loading' : 'mdi-download' }}
            </v-icon>
            Active
            <v-chip v-if="activeDownloads.length" size="small" color="info" class="ml-2">
              {{ activeDownloads.length }}
            </v-chip>
            <v-spacer />
            <v-btn
              v-if="activeDownloads.length"
              icon
              size="x-small"
              variant="text"
              @click="refreshActive"
            >
              <v-icon>mdi-refresh</v-icon>
            </v-btn>
          </v-card-title>
          <v-card-text>
            <v-list v-if="activeDownloads.length" density="compact">
              <v-list-item v-for="dl in activeDownloads" :key="dl.id">
                <template v-slot:prepend>
                  <v-icon :color="dl.status === 'running' ? 'info' : 'warning'" size="small">
                    {{ dl.status === 'running' ? 'mdi-loading mdi-spin' : 'mdi-clock-outline' }}
                  </v-icon>
                </template>
                <v-list-item-title class="text-body-2">
                  {{ getDownloadLabel(dl) }}
                </v-list-item-title>
                <v-list-item-subtitle>
                  <v-chip size="x-small" :color="dl.status === 'running' ? 'info' : 'warning'" variant="tonal">
                    {{ dl.status }}
                  </v-chip>
                </v-list-item-subtitle>
              </v-list-item>
            </v-list>
            <div v-else class="text-center text-grey py-4">
              <v-icon size="32" class="mb-2">mdi-check-circle-outline</v-icon>
              <div>No active downloads</div>
            </div>
          </v-card-text>
        </v-card>
      </v-col>

      <!-- Recent Activity -->
      <v-col cols="12" md="8">
        <v-card>
          <v-card-title>
            Recent Activity
            <v-chip v-if="recentActivity.length" size="small" class="ml-2" variant="tonal">
              Last 7 days
            </v-chip>
          </v-card-title>
          <v-card-text>
            <v-list v-if="recentActivity.length">
              <v-list-item
                v-for="download in recentActivity"
                :key="download.id"
              >
                <template v-slot:prepend>
                  <v-icon :color="getStatusColor(download.status)">
                    {{ getStatusIcon(download.status) }}
                  </v-icon>
                </template>
                <v-list-item-title>
                  {{ getDownloadLabel(download) }}
                </v-list-item-title>
                <v-list-item-subtitle>
                  {{ formatRelativeTime(download.created_at) }}
                  <span v-if="download.file_count > 0" class="text-success ml-2">
                    {{ download.file_count }} new file{{ download.file_count !== 1 ? 's' : '' }}
                  </span>
                </v-list-item-subtitle>
                <template v-slot:append>
                  <v-chip
                    :color="getStatusColor(download.status)"
                    size="small"
                    variant="tonal"
                  >
                    {{ download.status === 'completed' ? 'new content' : download.status }}
                  </v-chip>
                </template>
              </v-list-item>
            </v-list>
            <div v-else class="text-center text-grey py-4">
              No recent activity (failures or new downloads)
            </div>
          </v-card-text>
          <v-card-actions>
            <v-btn variant="text" to="/downloads">View All Downloads</v-btn>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>

    <v-row class="mt-4">
      <!-- Sources needing attention -->
      <v-col cols="12">
        <v-card>
          <v-card-title>
            Sources Needing Attention
            <v-chip class="ml-2" color="error" size="small" v-if="sourcesWithErrors.length">
              {{ sourcesWithErrors.length }}
            </v-chip>
          </v-card-title>
          <v-card-text>
            <v-table v-if="sourcesWithErrors.length">
              <thead>
                <tr>
                  <th>Source</th>
                  <th>Last Error</th>
                  <th>Last Check</th>
                  <th>Actions</th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="source in sourcesWithErrors" :key="source.id">
                  <td>{{ getSourceLabel(source) }}</td>
                  <td>
                    <v-chip color="error" size="small">
                      {{ source.last_error_type || 'failed' }}
                    </v-chip>
                  </td>
                  <td>{{ formatDate(source.last_check) }}</td>
                  <td>
                    <v-btn
                      size="small"
                      variant="text"
                      color="primary"
                      @click="retrySource(source)"
                    >
                      Retry
                    </v-btn>
                    <v-btn
                      size="small"
                      variant="text"
                      to="/subscriptions"
                    >
                      View
                      <v-tooltip activator="parent">View in Subscriptions</v-tooltip>
                    </v-btn>
                  </td>
                </tr>
              </tbody>
            </v-table>
            <div v-else class="text-center text-grey py-4">
              <v-icon size="48" class="mb-2">mdi-check-circle-outline</v-icon>
              <div>All sources are healthy!</div>
            </div>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useSourcesStore } from '../stores/sources'
import { useDownloadsStore } from '../stores/downloads'
import { useCredentialsStore } from '../stores/credentials'
import { useNotificationStore } from '../stores/notifications'
import { settingsApi, downloadsApi } from '../services/api'

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

// Supported platforms for credential status
const supportedPlatforms = ['patreon', 'subscribestar', 'hentaifoundry', 'discord', 'pixiv', 'deviantart']

// State
const checkingAll = ref(false)
const retryingAll = ref(false)
const resettingOrphaned = ref(false)
const storageStats = ref(null)
const activeDownloads = ref([])
const loadingStats = ref(true)
const loadingActivity = ref(true)
const loadingStorage = ref(true)
const refreshingStorage = ref(false)
let refreshInterval = null

// Computed
const stats = computed(() => downloadsStore.stats)
const recentActivity = computed(() => downloadsStore.recentActivity)

// Sources with recent failures - derived from recent activity
// Only shows sources where a recent download failed (not cumulative error_count)
const sourcesWithErrors = computed(() => {
  const failedDownloads = recentActivity.value.filter(d => d.status === 'failed')
  // Group by source_id and keep unique sources with their most recent failure
  const sourceMap = new Map()
  for (const dl of failedDownloads) {
    if (dl.source_id && !sourceMap.has(dl.source_id)) {
      sourceMap.set(dl.source_id, {
        id: dl.source_id,
        subscription_name: dl.subscription_name,
        platform: dl.platform,
        last_error_type: dl.error_type,
        last_check: dl.created_at,
      })
    }
  }
  return Array.from(sourceMap.values()).slice(0, 5)
})

const failedCount = computed(() => stats.value?.active_failed || 0)
const activeDownloadsCount = computed(() =>
  (stats.value?.queued || 0) + (stats.value?.running || 0)
)
// Running jobs that might be stuck (shows count for UI, actual stuck detection happens server-side)
const stuckRunningCount = computed(() => stats.value?.running || 0)

onMounted(() => {
  // Load data in background - DON'T await, let UI render immediately
  loadDashboardData()
  // Start auto-refresh for running downloads
  startAutoRefresh()
})

onUnmounted(() => {
  stopAutoRefresh()
})

function loadDashboardData() {
  // Fire off all requests in parallel, don't block UI
  // Each section handles its own loading state
  sourcesStore.fetchSources().catch(e => console.error('Failed to fetch sources:', e))
  credentialsStore.fetchCredentials().catch(e => console.error('Failed to fetch credentials:', e))

  downloadsStore.fetchStats()
    .catch(e => console.error('Failed to fetch stats:', e))
    .finally(() => loadingStats.value = false)

  downloadsStore.fetchRecentActivity({ limit: 10 })
    .catch(e => console.error('Failed to fetch recent activity:', e))
    .finally(() => loadingActivity.value = false)

  fetchActiveDownloads()

  // Storage stats can be slow - load independently
  fetchStorageStats()
}

async function fetchActiveDownloads() {
  try {
    // Fetch both queued and running downloads
    const [queuedResponse, runningResponse] = await Promise.all([
      downloadsStore.fetchDownloads({ status: 'queued', per_page: 20 }),
      downloadsStore.fetchDownloads({ status: 'running', per_page: 20 }),
    ])
    // Combine and sort: running first, then queued
    const running = runningResponse.items.filter(d => d.status === 'running')
    const queued = queuedResponse.items.filter(d => d.status === 'queued')
    activeDownloads.value = [...running, ...queued]
  } catch (e) {
    console.error('Failed to fetch active downloads:', e)
  }
}

async function fetchStorageStats() {
  loadingStorage.value = true
  try {
    const response = await settingsApi.get()
    storageStats.value = response.data.storage_stats
  } catch (e) {
    console.error('Failed to fetch storage stats:', e)
  } finally {
    loadingStorage.value = false
  }
}

async function refreshStorageStats() {
  refreshingStorage.value = true
  try {
    await settingsApi.refreshStorageStats()
    notifications.success('Storage stats refresh queued')
    // Wait a moment then fetch updated stats
    setTimeout(() => fetchStorageStats(), 3000)
  } catch (e) {
    console.error('Failed to refresh storage stats:', e)
    notifications.error('Failed to refresh storage stats')
  } finally {
    refreshingStorage.value = false
  }
}

function startAutoRefresh() {
  // Refresh active downloads every 5 seconds when there are active downloads
  refreshInterval = setInterval(async () => {
    if (activeDownloads.value.length > 0 || activeDownloadsCount.value > 0) {
      await fetchActiveDownloads()
      await downloadsStore.fetchStats()
      await downloadsStore.fetchRecentActivity({ limit: 10 })
    }
  }, 5000)
}

function stopAutoRefresh() {
  if (refreshInterval) {
    clearInterval(refreshInterval)
    refreshInterval = null
  }
}

async function refreshActive() {
  await fetchActiveDownloads()
}

async function checkAllSources() {
  checkingAll.value = true
  try {
    const enabledSources = sourcesStore.sources.filter(s => s.enabled)
    const results = await Promise.allSettled(
      enabledSources.map(source => sourcesStore.triggerCheck(source.id))
    )
    const queued = results.filter(r => r.status === 'fulfilled').length
    const failed = results.filter(r => r.status === 'rejected').length
    if (failed > 0) {
      notifications.success(`Queued ${queued} sources (${failed} failed to queue)`)
    } else {
      notifications.success(`Queued checks for ${queued} sources`)
    }
    await fetchActiveDownloads()
    await downloadsStore.fetchStats()
  } catch (error) {
    notifications.error(`Failed to check sources: ${error.message}`)
  } finally {
    checkingAll.value = false
  }
}

async function retryAllFailed() {
  retryingAll.value = true
  try {
    const response = await downloadsStore.fetchDownloads({ status: 'failed', per_page: 100, exclude_superseded: true })
    const failed = response.items
    let retried = 0
    for (const dl of failed) {
      try {
        await downloadsStore.retryDownload(dl.id)
        retried++
      } catch (e) {
        console.error(`Failed to retry ${dl.id}:`, e)
      }
    }
    notifications.success(`Queued retry for ${retried} downloads`)
    await downloadsStore.fetchStats()
    await fetchActiveDownloads()
  } catch (error) {
    notifications.error(`Failed to retry downloads: ${error.message}`)
  } finally {
    retryingAll.value = false
  }
}

async function resetOrphanedJobs() {
  resettingOrphaned.value = true
  try {
    const response = await downloadsApi.resetOrphaned(0)  // 0 = reset all running
    notifications.success(response.data.message || `Reset ${response.data.reset_count} stuck jobs`)
    await downloadsStore.fetchStats()
    await fetchActiveDownloads()
  } catch (error) {
    notifications.error(`Failed to reset stuck jobs: ${error.message}`)
  } finally {
    resettingOrphaned.value = false
  }
}

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

function getPlatformIcon(platform) {
  const icons = {
    patreon: 'mdi-patreon',
    subscribestar: 'mdi-star',
    hentaifoundry: 'mdi-palette',
    discord: 'mdi-discord',
    pixiv: 'mdi-alpha-p-box',
    deviantart: 'mdi-deviantart',
  }
  return icons[platform] || 'mdi-web'
}

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

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

function formatRelativeTime(dateStr) {
  if (!dateStr) return 'Unknown'
  const date = new Date(dateStr)
  const now = new Date()
  const diffMs = now - date
  const diffMins = Math.floor(diffMs / 60000)
  const diffHours = Math.floor(diffMs / 3600000)
  const diffDays = Math.floor(diffMs / 86400000)

  if (diffMins < 1) return 'Just now'
  if (diffMins < 60) return `${diffMins} min${diffMins !== 1 ? 's' : ''} ago`
  if (diffHours < 24) return `${diffHours} hour${diffHours !== 1 ? 's' : ''} ago`
  if (diffDays < 7) return `${diffDays} day${diffDays !== 1 ? 's' : ''} ago`
  return date.toLocaleDateString()
}

function truncate(str, length) {
  if (!str) return ''
  if (str.length <= length) return str
  return str.substring(0, length) + '...'
}

function getDownloadLabel(download) {
  if (download.subscription_name && download.platform) {
    return `${download.subscription_name}:${download.platform}`
  }
  // Fallback to truncated URL if source info not available
  return truncate(download.url, 35)
}

function getSourceLabel(source) {
  const name = source.subscription_name || source.subscription?.name || 'Unknown'
  return `${name}:${source.platform}`
}

async function retrySource(source) {
  try {
    await sourcesStore.triggerCheck(source.id)
    notifications.success(`Queued check for ${getSourceLabel(source)}`)
    // Refresh recent activity after retrying
    await downloadsStore.fetchRecentActivity({ limit: 10 })
  } catch (error) {
    notifications.error(`Failed to queue check: ${error.message}`)
  }
}
</script>
