<template>
  <!-- Centered, width-capped column so the tab strip + every panel sit in a
       tidy centered measure rather than stretching full-width (operator
       2026-06-18). v-container is margin-auto by default; the cap keeps long
       maintenance/import panels readable. -->
  <v-container class="pt-2 pb-6 fc-settings">
    <!-- Sticky tabs: operator-flagged 2026-05-25 — long Import / Maintenance
         panels pushed the tab strip out of the viewport, forcing a scroll-
         to-top just to change tab. AppShell's TopNav is 64px sticky, so the
         tab strip lives directly under it. The .fc-chrome-continues fade
         continues the nav's gradient across the strip (operator 2026-07-13). -->
    <v-tabs
      v-model="tab" color="accent" class="mb-4 fc-chrome-continues"
      style="position: sticky; top: var(--fc-nav-h, 64px); z-index: 4;"
    >
      <v-tab value="overview">Overview</v-tab>
      <v-tab value="system">System</v-tab>
      <v-tab value="activity">Activity</v-tab>
      <v-tab value="cleanup">Cleanup</v-tab>
      <v-tab value="maintenance">Maintenance</v-tab>
    </v-tabs>

    <v-window v-model="tab">
      <v-window-item value="overview">
        <SystemStatsCards :stats="system.stats" />
        <SystemActivitySummary
          class="mt-4"
          @open-activity="tab = 'activity'"
        />
        <!-- Health strip (2026-07-02): the same GPU + downloads panels the
             Activity tab uses — Overview answers "is everything healthy?"
             across ALL systems, not just the Celery queues above. -->
        <div class="fc-health-row mt-4">
          <GpuActivityPanel @open-maintenance="tab = 'maintenance'" />
          <DownloadsActivityPanel />
        </div>
        <v-alert
          v-if="system.stats && (system.stats.tasks.pending + system.stats.tasks.queued) > 0"
          type="info" variant="tonal" class="mt-4" closable
        >
          {{ system.stats.tasks.pending + system.stats.tasks.queued }} import task(s) pending.
          <v-btn variant="text" size="small" @click="tab = 'activity'">View in Activity</v-btn>
        </v-alert>
      </v-window-item>

      <!-- Is every part of the stack still running (milestone 365). Sits
           beside Activity deliberately: Activity answers "what is the queue
           doing", this answers "is anything left to do it". -->
      <v-window-item value="system">
        <SystemHealthTab />
      </v-window-item>

      <v-window-item value="activity">
        <SystemActivityTab @open-maintenance="tab = 'maintenance'" />
      </v-window-item>

      <v-window-item value="cleanup">
        <CleanupView />
      </v-window-item>

      <v-window-item value="maintenance">
        <MaintenancePanel />
      </v-window-item>
    </v-window>

    <!-- Which build is this? With no version image tags (milestone 318) the
         instance's own report is the only answer, so it is shown rather than
         hidden. The instinct to treat it as information disclosure does not
         survive contact: the JS bundle and asset hashes fingerprint the build
         anyway, and "I'm on 2026.08.28.1249" is the single most useful line in
         a bug report.

         Channel sits BESIDE the version, never inside it (rule 149) — a
         `-dev` suffix would read as a 0 segment to the extension's comparator
         and make every dev build compare equal (#2993). -->
    <div v-if="system.buildLoaded" class="text-caption text-medium-emphasis text-center mt-8">
      FabledCurator {{ system.buildVersion || 'unknown' }}
      <span v-if="system.buildChannel"> · {{ system.buildChannel }}</span>
    </div>
  </v-container>
</template>

<script setup>
import { onMounted, onUnmounted, watch } from 'vue'
import { useSystemStore } from '../stores/system.js'
import SystemStatsCards from '../components/settings/SystemStatsCards.vue'
import SystemActivitySummary from '../components/settings/SystemActivitySummary.vue'
import SystemActivityTab from '../components/settings/SystemActivityTab.vue'
import SystemHealthTab from '../components/settings/SystemHealthTab.vue'
import GpuActivityPanel from '../components/settings/GpuActivityPanel.vue'
import DownloadsActivityPanel from '../components/settings/DownloadsActivityPanel.vue'
import MaintenancePanel from '../components/settings/MaintenancePanel.vue'
import CleanupView from './CleanupView.vue'
import { useTabQuery } from '../composables/useTabQuery.js'
import { useMLStore } from '../stores/ml.js'

// ?tab= sync (the same composable Browse/Subscriptions use) so a tab can be
// linked TO — the health dot beside the brand points at ?tab=system, and the
// old /system path redirects there.
const VALID_TABS = ['overview', 'system', 'activity', 'cleanup', 'maintenance']
const { tab } = useTabQuery(VALID_TABS, 'overview')
const system = useSystemStore()
const mlStore = useMLStore()

let pollId = null

function startPolling() {
  if (pollId) return
  system.refreshStats()
  pollId = setInterval(() => {
    if (!document.hidden) system.refreshStats()
  }, 5000)
}

function stopPolling() {
  if (pollId) { clearInterval(pollId); pollId = null }
}

onMounted(startPolling)
onUnmounted(stopPolling)

watch(tab, (t) => {
  if (t === 'maintenance') mlStore.loadSettings()
})
</script>

<style scoped>
/* Centered, capped measure for the whole Settings surface (tabs + panels). */
.fc-settings {
  max-width: 1140px;
}
/* Overview health strip: the two pulse panels side by side, stacking on
   narrow screens. Cancel the panels' own bottom margin — the row owns gaps. */
.fc-health-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 16px;
  align-items: start;
}
.fc-health-row :deep(.v-card) { margin-bottom: 0 !important; }
</style>
