<template>
  <div>
    <div class="mb-4 md:mb-8 flex items-start justify-between gap-4">
      <div class="min-h-[4.5rem]">
        <h1 class="text-3xl font-bold text-white mb-2 drop-shadow-[0_2px_8px_rgba(0,0,0,0.6)]">
          {{ line1Text }}<span v-if="showCaretLine1" class="typing-caret"></span>
        </h1>
        <p class="text-white/80">
          {{ line2Text }}<span v-if="showCaretLine2" class="typing-caret"></span>
        </p>
      </div>
      <!-- Desktop: tabs inline with header -->
      <div
        v-if="!uiMode.isChat"
        class="hidden md:flex mode-switcher flex-shrink-0 transition-opacity duration-500"
        :class="{ 'opacity-0 pointer-events-none': showWelcomeBlock && !animateCards }"
      >
        <button class="mode-switcher-btn" :class="{ 'mode-switcher-btn-active': homeTab === 'dashboard' }" @click="homeTab = 'dashboard'">Dashboard</button>
        <button class="mode-switcher-btn" :class="{ 'mode-switcher-btn-active': homeTab === 'setup' }" @click="homeTab = 'setup'">Setup</button>
      </div>
    </div>

    <!-- Tab bar + content (all non-chat modes) -->
    <template v-if="!uiMode.isChat">
      <!-- Mobile: full-width tabs -->
      <div
        class="md:hidden mode-switcher mb-6 w-full transition-opacity duration-500"
        :class="{ 'opacity-0 pointer-events-none': showWelcomeBlock && !animateCards }"
      >
        <button class="mode-switcher-btn" :class="{ 'mode-switcher-btn-active': homeTab === 'dashboard' }" @click="homeTab = 'dashboard'">Dashboard</button>
        <button class="mode-switcher-btn" :class="{ 'mode-switcher-btn-active': homeTab === 'setup' }" @click="homeTab = 'setup'">Setup</button>
      </div>

      <!-- Setup tab: goal-based cards -->
      <EasyHome
        v-if="homeTab === 'setup'"
        :show="!showWelcomeBlock || animateCards"
        :animate="animateCards"
      />

      <!-- Dashboard tab: overview cards -->
      <div
        v-else
        class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8 transition-opacity duration-300"
        :class="{ 'opacity-0 pointer-events-none': showWelcomeBlock && !animateCards }"
      >
      <!-- My Apps Overview -->
      <div
        data-controller-container
        tabindex="0"
        class="home-card controller-focusable"
        :class="{ 'home-card-animate': animateCards }"
        style="--card-stagger: 0"
      >
        <div class="home-card-shell">
          <div class="home-card-inner p-6 flex flex-col h-full min-h-0">
            <div class="home-card-header flex items-start justify-between mb-4 shrink-0">
              <div class="home-card-text">
                <h2 class="text-xl font-semibold text-white mb-1">My Apps</h2>
                <p class="text-sm text-white/70">Manage your installed applications</p>
              </div>
              <RouterLink to="/dashboard/apps" class="text-white/60 hover:text-white transition-colors">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                </svg>
              </RouterLink>
            </div>
            <div class="home-card-stats grid grid-cols-1 sm:grid-cols-2 gap-4 mb-4 flex-1 min-h-0">
              <div class="p-4 bg-white/5 rounded-lg">
                <p class="text-xs text-white/60 mb-1">Installed</p>
                <p class="text-2xl font-bold text-white">{{ appCount }}</p>
              </div>
              <div class="p-4 bg-white/5 rounded-lg">
                <p class="text-xs text-white/60 mb-1">Running</p>
                <p class="text-2xl font-bold text-white">{{ runningCount }}</p>
              </div>
            </div>
            <div class="home-card-buttons flex gap-2 mt-auto pt-4 shrink-0">
              <RouterLink to="/dashboard/marketplace" class="home-card-btn flex-1 px-4 py-2 glass-button rounded-lg text-sm font-medium text-center transition-colors">
                Browse Store
              </RouterLink>
              <RouterLink to="/dashboard/apps" class="home-card-btn flex-1 px-4 py-2 glass-button rounded-lg text-sm font-medium text-center transition-colors">
                Manage Apps
              </RouterLink>
            </div>
          </div>
        </div>
      </div>

      <!-- Cloud Overview -->
      <div
        data-controller-container
        tabindex="0"
        class="home-card controller-focusable"
        :class="{ 'home-card-animate': animateCards }"
        style="--card-stagger: 1"
      >
        <div class="home-card-shell">
          <div class="home-card-inner p-6 flex flex-col h-full min-h-0">
            <div class="home-card-header flex items-start justify-between mb-4 shrink-0">
              <div class="home-card-text">
                <h2 class="text-xl font-semibold text-white mb-1">Cloud</h2>
                <p class="text-sm text-white/70">Cloud services and storage</p>
              </div>
              <RouterLink to="/dashboard/cloud" class="text-white/60 hover:text-white transition-colors">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                </svg>
              </RouterLink>
            </div>
            <div class="home-card-stats grid grid-cols-1 sm:grid-cols-2 gap-4 mb-4 flex-1 min-h-0">
              <div class="p-4 bg-white/5 rounded-lg">
                <p class="text-xs text-white/60 mb-1">Storage Used</p>
                <p class="text-2xl font-bold text-white">{{ cloudStorageDisplay }}</p>
              </div>
              <div class="p-4 bg-white/5 rounded-lg">
                <p class="text-xs text-white/60 mb-1">Folders</p>
                <p class="text-2xl font-bold text-white">{{ cloudFolderDisplay }}</p>
              </div>
            </div>
            <div class="home-card-buttons flex gap-2 mt-auto pt-4 shrink-0">
              <RouterLink to="/dashboard/cloud" class="home-card-btn flex-1 px-4 py-2 glass-button rounded-lg text-sm font-medium text-center transition-colors">
                View Folders
              </RouterLink>
              <button @click="uploadFiles" class="home-card-btn flex-1 px-4 py-2 glass-button rounded-lg text-sm font-medium text-center transition-colors">
                Upload Files
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- Network Overview -->
      <div
        data-controller-container
        tabindex="0"
        class="home-card controller-focusable"
        :class="{ 'home-card-animate': animateCards }"
        style="--card-stagger: 2"
      >
        <div class="home-card-shell">
          <div class="home-card-inner p-6 flex flex-col h-full min-h-0">
            <div class="home-card-header flex items-start justify-between mb-4 shrink-0">
              <div class="home-card-text">
                <h2 class="text-xl font-semibold text-white mb-1">Network</h2>
                <p class="text-sm text-white/70">Network infrastructure and Web3 services</p>
              </div>
              <RouterLink to="/dashboard/server" class="text-white/60 hover:text-white transition-colors">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                </svg>
              </RouterLink>
            </div>
            <div class="home-card-stats space-y-3 mb-4 flex-1 min-h-0">
              <div class="flex items-center justify-between p-3 bg-white/5 rounded-lg">
                <div class="flex items-center gap-3">
                  <div class="w-2 h-2 rounded-full" :class="servicesDotColor"></div>
                  <span class="text-sm text-white/80">Services Status</span>
                </div>
                <span class="text-sm font-medium" :class="servicesStatusColor">{{ servicesStatusText }}</span>
              </div>
              <div class="flex items-center justify-between p-3 bg-white/5 rounded-lg">
                <div class="flex items-center gap-3">
                  <div class="w-2 h-2 rounded-full" :class="connectivityDotColor"></div>
                  <span class="text-sm text-white/80">Connectivity</span>
                </div>
                <span class="text-sm font-medium" :class="connectivityColor">{{ connectivityText }}</span>
              </div>
              <div class="flex items-center justify-between p-3 bg-white/5 rounded-lg">
                <div class="flex items-center gap-3">
                  <div class="w-2 h-2 rounded-full bg-blue-400"></div>
                  <span class="text-sm text-white/80">Running Apps</span>
                </div>
                <span class="text-sm text-white/80 font-medium">{{ runningCount }}</span>
              </div>
            </div>
            <div class="home-card-buttons flex gap-2 mt-auto pt-4 shrink-0">
              <RouterLink to="/dashboard/server" class="home-card-btn flex-1 px-4 py-2 glass-button rounded-lg text-sm font-medium text-center transition-colors">
                Manage Network
              </RouterLink>
              <button class="home-card-btn px-4 py-2 glass-button rounded-lg text-sm font-medium transition-colors" @click="() => {}">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- Web5 Overview -->
      <div
        data-controller-container
        tabindex="0"
        class="home-card controller-focusable"
        :class="{ 'home-card-animate': animateCards }"
        style="--card-stagger: 3"
      >
        <div class="home-card-shell">
          <div class="home-card-inner p-6 flex flex-col h-full min-h-0">
            <div class="home-card-header flex items-start justify-between mb-4 shrink-0">
              <div class="home-card-text">
                <h2 class="text-xl font-semibold text-white mb-1">Web5</h2>
                <p class="text-sm text-white/70">Decentralized identity and data protocols</p>
              </div>
              <RouterLink to="/dashboard/web5" class="text-white/60 hover:text-white transition-colors">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                </svg>
              </RouterLink>
            </div>
            <div class="home-card-stats space-y-3 mb-4 flex-1 min-h-0">
              <div class="flex items-center justify-between p-3 bg-white/5 rounded-lg">
                <div class="flex items-center gap-3">
                  <div class="w-2 h-2 rounded-full bg-green-400"></div>
                  <span class="text-sm text-white/80">DID Status</span>
                </div>
                <span class="text-sm text-green-400 font-medium">Active</span>
              </div>
              <div class="flex items-center justify-between p-3 bg-white/5 rounded-lg">
                <div class="flex items-center gap-3">
                  <div class="w-2 h-2 rounded-full bg-green-400"></div>
                  <span class="text-sm text-white/80">DWN Sync</span>
                </div>
                <span class="text-sm text-green-400 font-medium">Synced</span>
              </div>
              <div class="flex items-center justify-between p-3 bg-white/5 rounded-lg">
                <div class="flex items-center gap-3">
                  <span class="text-lg text-orange-500 font-bold">₿</span>
                  <span class="text-sm text-white/80">Networking Profits</span>
                </div>
                <span class="text-sm text-orange-500 font-medium">₿0.024</span>
              </div>
            </div>
            <div class="home-card-buttons flex gap-2 mt-auto pt-4 shrink-0">
              <RouterLink to="/dashboard/web5" class="home-card-btn flex-1 px-4 py-2 glass-button rounded-lg text-sm font-medium text-center transition-colors">
                Manage Web5
              </RouterLink>
              <button class="home-card-btn px-4 py-2 glass-button rounded-lg text-sm font-medium transition-colors" @click="() => {}">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>
      <!-- System Stats -->
      <div
        data-controller-container
        tabindex="0"
        class="home-card controller-focusable lg:col-span-2"
        :class="{ 'home-card-animate': animateCards }"
        style="--card-stagger: 4"
      >
        <div class="home-card-shell">
          <div class="home-card-inner p-6 flex flex-col h-full min-h-0">
            <div class="home-card-header flex items-start justify-between mb-4 shrink-0">
              <div class="home-card-text">
                <h2 class="text-xl font-semibold text-white mb-1">System</h2>
                <p class="text-sm text-white/70">{{ systemUptimeDisplay }}</p>
              </div>
              <RouterLink to="/dashboard/server" class="text-white/60 hover:text-white transition-colors">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
                </svg>
              </RouterLink>
            </div>
            <div class="home-card-stats grid grid-cols-1 sm:grid-cols-3 gap-4 flex-1 min-h-0">
              <div class="p-4 bg-white/5 rounded-lg">
                <div class="flex items-center justify-between mb-2">
                  <p class="text-xs text-white/60">CPU</p>
                  <p class="text-sm font-medium" :class="gaugeTextColor(systemStats.cpuPercent)">{{ systemStats.cpuPercent.toFixed(0) }}%</p>
                </div>
                <div class="w-full h-2 bg-white/10 rounded-full overflow-hidden">
                  <div class="h-full rounded-full transition-all duration-500" :class="gaugeBarColor(systemStats.cpuPercent)" :style="{ width: systemStats.cpuPercent + '%' }"></div>
                </div>
              </div>
              <div class="p-4 bg-white/5 rounded-lg">
                <div class="flex items-center justify-between mb-2">
                  <p class="text-xs text-white/60">RAM</p>
                  <p class="text-sm font-medium" :class="gaugeTextColor(systemStats.memPercent)">{{ formatBytes(systemStats.memUsed) }} / {{ formatBytes(systemStats.memTotal) }}</p>
                </div>
                <div class="w-full h-2 bg-white/10 rounded-full overflow-hidden">
                  <div class="h-full rounded-full transition-all duration-500" :class="gaugeBarColor(systemStats.memPercent)" :style="{ width: systemStats.memPercent + '%' }"></div>
                </div>
              </div>
              <div class="p-4 bg-white/5 rounded-lg">
                <div class="flex items-center justify-between mb-2">
                  <p class="text-xs text-white/60">Disk</p>
                  <p class="text-sm font-medium" :class="gaugeTextColor(systemStats.diskPercent)">{{ formatBytes(systemStats.diskUsed) }} / {{ formatBytes(systemStats.diskTotal) }}</p>
                </div>
                <div class="w-full h-2 bg-white/10 rounded-full overflow-hidden">
                  <div class="h-full rounded-full transition-all duration-500" :class="gaugeBarColor(systemStats.diskPercent)" :style="{ width: systemStats.diskPercent + '%' }"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Quick Start Goals - shown in Pro mode below the overview cards -->
    <div
      v-if="homeTab === 'dashboard' && showQuickStart"
      class="home-card transition-opacity duration-300"
      :class="{ 'home-card-animate': animateCards, 'opacity-0 pointer-events-none': showWelcomeBlock && !animateCards }"
      style="--card-stagger: 5"
    >
      <div class="home-card-shell">
        <div class="home-card-inner px-6 py-6">
          <div class="flex items-start justify-between mb-2">
            <div>
              <h2 class="text-xl font-semibold text-white/96 mb-1">Quick Start Goals</h2>
              <p class="text-sm text-white/60 mb-4">Not sure where to start? Try a guided setup.</p>
            </div>
            <button
              @click="dismissQuickStart"
              class="text-white/40 hover:text-white/80 transition-colors p-1 -mt-1 -mr-1"
              title="Dismiss"
            >
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          </div>
          <div class="grid grid-cols-1 md:grid-cols-3 gap-3">
            <RouterLink
              v-for="goal in topGoals"
              :key="goal.id"
              :to="`/dashboard/goals/${goal.id}`"
              class="home-card-btn path-action-button path-action-button--continue flex items-center justify-center gap-3"
            >
              <span>{{ goal.title }}</span>
            </RouterLink>
          </div>
        </div>
      </div>
    </div>

    </template>

    <!-- Chat Mode: redirect to Chat view -->
    <div v-if="uiMode.isChat" class="flex flex-col items-center justify-center min-h-[40vh]">
      <RouterLink to="/dashboard/chat" class="glass-button rounded-lg px-8 py-4 text-lg font-medium">
        Open AI Assistant
      </RouterLink>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch, onBeforeUnmount, onMounted } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import { useAppStore } from '../stores/app'
import { useAppLauncherStore } from '@/stores/appLauncher'
import { useLoginTransitionStore } from '../stores/loginTransition'
import { useUIModeStore } from '@/stores/uiMode'
import { PackageState } from '../types/api'
import { playTypingSound } from '@/composables/useLoginSounds'
import { GOALS } from '@/data/goals'
import EasyHome from '@/components/EasyHome.vue'
import { fileBrowserClient } from '@/api/filebrowser-client'
import { rpcClient } from '@/api/rpc-client'

const router = useRouter()
const uiMode = useUIModeStore()
const homeTab = ref<'dashboard' | 'setup'>('dashboard')
const topGoals = GOALS.slice(0, 3)

// Apps required by the top 3 goals — if all installed, no need to show Quick Start
const QUICK_START_APPS = [...new Set(topGoals.flatMap((g) => g.requiredApps))]
const QUICK_START_KEY = 'archipelago-quick-start-dismissed'
const QUICK_START_RESHOW_LOGINS = 5

const store = useAppStore()
const loginTransition = useLoginTransitionStore()

const LINE1 = "Welcome Noderunner"
const LINE2 = "Here's an overview of your sovereign life"
const MS_PER_CHAR = 55

const displayLine1 = ref('')
const displayLine2 = ref('')
const showCaretLine1 = ref(false)
const showCaretLine2 = ref(false)
const showWelcomeBlock = ref(false)
const hasTypedWelcome = ref(false)
const animateCards = ref(false)
let typingInterval: ReturnType<typeof setInterval> | null = null

const line1Text = computed(() =>
  showWelcomeBlock.value ? displayLine1.value : LINE1
)
const line2Text = computed(() =>
  showWelcomeBlock.value ? displayLine2.value : LINE2
)

onBeforeUnmount(() => {
  if (typingInterval) clearInterval(typingInterval)
  if (systemStatsInterval) clearInterval(systemStatsInterval)
})

watch(() => loginTransition.pendingWelcomeTyping, (pending) => {
  if (pending) showWelcomeBlock.value = true
})

watch(() => loginTransition.startWelcomeTyping, (shouldStart) => {
  if (!shouldStart || hasTypedWelcome.value) return
  hasTypedWelcome.value = true
  showWelcomeBlock.value = true
  displayLine1.value = ''
  displayLine2.value = ''
  showCaretLine1.value = true
  showCaretLine2.value = false

  playTypingSound()
  animateCards.value = true

  let i = 0
  typingInterval = setInterval(() => {
    if (i < LINE1.length) {
      displayLine1.value = LINE1.slice(0, i + 1)
      i++
    } else if (i < LINE1.length + LINE2.length) {
      showCaretLine1.value = false
      showCaretLine2.value = true
      displayLine2.value = LINE2.slice(0, i - LINE1.length + 1)
      i++
    } else {
      if (typingInterval) clearInterval(typingInterval)
      typingInterval = null
      showCaretLine2.value = false
      loginTransition.setStartWelcomeTyping(false)
    }
  }, MS_PER_CHAR)
}, { immediate: true })

// @ts-ignore - Computed kept for future use
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const version = computed(() => store.serverInfo?.version || '0.0.0')
const packages = computed(() => store.packages)
const appCount = computed(() => Object.keys(packages.value).length)
const runningCount = computed(() =>
  Object.values(packages.value).filter(pkg => pkg.state === PackageState.Running).length
)

// Network card computed values
const servicesAllRunning = computed(() =>
  appCount.value > 0 && runningCount.value === appCount.value
)
const servicesStatusText = computed(() => {
  if (appCount.value === 0) return 'No Apps'
  return servicesAllRunning.value ? 'All Running' : `${runningCount.value}/${appCount.value} Running`
})
const servicesStatusColor = computed(() =>
  appCount.value === 0 ? 'text-white/60' : servicesAllRunning.value ? 'text-green-400' : 'text-yellow-400'
)
const servicesDotColor = computed(() =>
  appCount.value === 0 ? 'bg-white/40' : servicesAllRunning.value ? 'bg-green-400' : 'bg-yellow-400'
)
const connectivityText = computed(() => store.isConnected ? 'Connected' : 'Disconnected')
const connectivityColor = computed(() => store.isConnected ? 'text-green-400' : 'text-red-400')
const connectivityDotColor = computed(() => store.isConnected ? 'bg-green-400' : 'bg-red-400')

// Quick Start Goals dismiss logic
const quickStartDismissed = ref(false)

const allQuickStartAppsInstalled = computed(() =>
  QUICK_START_APPS.every((appId) => Object.keys(packages.value).includes(appId))
)

const showQuickStart = computed(() => {
  if (allQuickStartAppsInstalled.value) return false
  return !quickStartDismissed.value
})

function loadQuickStartState() {
  try {
    const raw = localStorage.getItem(QUICK_START_KEY)
    if (!raw) { quickStartDismissed.value = false; return }
    const data = JSON.parse(raw) as { dismissed: boolean; loginCount: number }
    if (!data.dismissed) { quickStartDismissed.value = false; return }
    // Re-show every N logins
    const loginCount = (data.loginCount || 0) + 1
    localStorage.setItem(QUICK_START_KEY, JSON.stringify({ dismissed: true, loginCount }))
    quickStartDismissed.value = loginCount % QUICK_START_RESHOW_LOGINS !== 0
  } catch {
    quickStartDismissed.value = false
  }
}

function dismissQuickStart() {
  quickStartDismissed.value = true
  try {
    localStorage.setItem(QUICK_START_KEY, JSON.stringify({ dismissed: true, loginCount: 0 }))
  } catch { /* ignore */ }
}

loadQuickStartState()

// Cloud data
const cloudStorageUsed = ref<number | null>(null)
const cloudFolderCount = ref<number | null>(null)

function formatBytes(bytes: number): string {
  if (bytes === 0) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(1024))
  const val = bytes / Math.pow(1024, i)
  return `${val < 10 ? val.toFixed(1) : Math.round(val)} ${units[i]}`
}

const cloudStorageDisplay = computed(() =>
  cloudStorageUsed.value !== null ? formatBytes(cloudStorageUsed.value) : '...'
)
const cloudFolderDisplay = computed(() =>
  cloudFolderCount.value !== null ? String(cloudFolderCount.value) : '...'
)

onMounted(async () => {
  try {
    const usage = await fileBrowserClient.getUsage()
    cloudStorageUsed.value = usage.totalSize
    cloudFolderCount.value = usage.folderCount
  } catch {
    // FileBrowser may not be running — leave as loading
  }
  loadSystemStats()
  systemStatsInterval = setInterval(loadSystemStats, 30000)
})

// System stats
const systemStats = reactive({
  cpuPercent: 0,
  memUsed: 0,
  memTotal: 0,
  memPercent: 0,
  diskUsed: 0,
  diskTotal: 0,
  diskPercent: 0,
  uptimeSecs: 0,
})

const systemUptimeDisplay = computed(() => {
  if (systemStats.uptimeSecs === 0) return 'System monitoring'
  const days = Math.floor(systemStats.uptimeSecs / 86400)
  const hours = Math.floor((systemStats.uptimeSecs % 86400) / 3600)
  if (days > 0) return `Uptime: ${days}d ${hours}h`
  const mins = Math.floor((systemStats.uptimeSecs % 3600) / 60)
  return `Uptime: ${hours}h ${mins}m`
})

function gaugeTextColor(pct: number): string {
  if (pct >= 90) return 'text-red-400'
  if (pct >= 70) return 'text-orange-400'
  return 'text-green-400'
}

function gaugeBarColor(pct: number): string {
  if (pct >= 90) return 'bg-red-400'
  if (pct >= 70) return 'bg-orange-400'
  return 'bg-green-400'
}

let systemStatsInterval: ReturnType<typeof setInterval> | null = null

async function loadSystemStats() {
  try {
    const res = await rpcClient.call<{
      cpu_usage_percent: number
      mem_used_bytes: number
      mem_total_bytes: number
      disk_used_bytes: number
      disk_total_bytes: number
      uptime_secs: number
    }>({ method: 'system.stats' })
    systemStats.cpuPercent = res.cpu_usage_percent
    systemStats.memUsed = res.mem_used_bytes
    systemStats.memTotal = res.mem_total_bytes
    systemStats.memPercent = res.mem_total_bytes > 0 ? (res.mem_used_bytes / res.mem_total_bytes) * 100 : 0
    systemStats.diskUsed = res.disk_used_bytes
    systemStats.diskTotal = res.disk_total_bytes
    systemStats.diskPercent = res.disk_total_bytes > 0 ? (res.disk_used_bytes / res.disk_total_bytes) * 100 : 0
    systemStats.uptimeSecs = res.uptime_secs
  } catch {
    // RPC unavailable — keep defaults
  }
}

function uploadFiles() {
  const pkg = packages.value['filebrowser']
  if (pkg && pkg.state === PackageState.Running) {
    const host = window.location.hostname
    useAppLauncherStore().open({ url: `http://${host}:8083`, title: 'File Browser' })
  } else {
    router.push('/dashboard/cloud')
  }
}

</script>

<style scoped>
.typing-caret::after {
  content: '';
  display: inline-block;
  width: 3px;
  height: 1.1em;
  background: #fbbf24;
  margin-left: 2px;
  vertical-align: text-bottom;
  animation: caret-blink 0.7s step-end infinite;
}

@keyframes caret-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* 2advanced-style card animation sequence */
.grid > .home-card {
  min-height: 280px;
}

.home-card-shell {
  background-color: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  border: 1px solid transparent;
  height: 100%;
}

.home-card-animate .home-card-shell {
  animation: card-fly-in 1.2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  animation-delay: calc(var(--card-stagger) * 0.18s);
  opacity: 0;
  transform: translateY(50px) scale(0.92);
}

@keyframes card-fly-in {
  0% {
    opacity: 0;
    transform: translateY(50px) scale(0.92);
    border-color: transparent;
  }
  75% {
    opacity: 1;
    transform: translateY(0) scale(1);
    border-color: transparent;
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
    border-color: rgba(255, 255, 255, 0.18);
  }
}

.home-card-inner {
  overflow: hidden;
  opacity: 0;
}

.home-card-animate .home-card-inner {
  animation: inner-draw 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  animation-delay: calc(var(--card-stagger) * 0.18s + 0.9s);
}

@keyframes inner-draw {
  0% {
    opacity: 0;
    clip-path: inset(0 100% 0 0);
  }
  15% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    clip-path: inset(0 0 0 0);
  }
}

.home-card-text {
  overflow: hidden;
}

.home-card-stats {
  overflow: hidden;
}

.home-card-btn {
  opacity: 0;
  transform: scale(0.5);
  border-color: transparent;
  min-height: 44px;
  padding-top: 10px;
  padding-bottom: 10px;
}

.home-card-animate .home-card-btn {
  animation: btn-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  animation-delay: calc(var(--card-stagger) * 0.18s + 1.5s);
}

@keyframes btn-pop {
  0% {
    opacity: 0;
    transform: scale(0.5);
    border-color: transparent;
  }
  85% {
    opacity: 1;
    transform: scale(1);
    border-color: transparent;
  }
  100% {
    opacity: 1;
    transform: scale(1);
    border-color: rgba(255, 255, 255, 0.18);
  }
}

/* When not animating, show everything */
.home-card:not(.home-card-animate) .home-card-inner,
.home-card:not(.home-card-animate) .home-card-btn {
  opacity: 1;
  animation: none;
  clip-path: none;
  transform: none;
  border-color: rgba(255, 255, 255, 0.18);
}

.home-card:not(.home-card-animate) .home-card-shell {
  border-color: rgba(255, 255, 255, 0.18);
}
</style>
