<template>
  <div class="p-6">
    <GettingStartedChecklist />

    <!-- Loading skeleton -->
    <div v-if="loading" class="space-y-6" aria-busy="true" aria-label="Loading dashboard data">
      <div class="h-6 w-48 bg-bg-elevated rounded animate-pulse" />
      <div class="grid grid-cols-4 gap-4">
        <div v-for="i in 4" :key="i" class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <div class="h-3 w-16 bg-bg-elevated rounded animate-pulse mb-2" />
          <div class="h-6 w-24 bg-bg-elevated rounded animate-pulse" />
        </div>
      </div>
      <div class="bg-bg-surface border border-border-subtle rounded-lg p-4"><div class="h-20 bg-bg-elevated rounded animate-pulse" /></div>
      <div class="grid grid-cols-2 gap-4">
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4"><div class="h-48 bg-bg-elevated rounded animate-pulse" /></div>
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4 space-y-2">
          <div v-for="i in 5" :key="i" class="h-8 bg-bg-elevated rounded animate-pulse" />
        </div>
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4"><div class="h-20 bg-bg-elevated rounded animate-pulse" /></div>
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4 space-y-2">
          <div v-for="i in 3" :key="i" class="h-12 bg-bg-elevated rounded animate-pulse" />
        </div>
      </div>
    </div>

    <div class="sr-only" aria-live="polite">
      {{ loading ? '' : 'Dashboard loaded' }}
    </div>

    <!-- Empty state -->
    <div v-if="!loading && isEmpty" class="flex flex-col items-center justify-center py-16">
      <Clock class="w-12 h-12 text-text-tertiary animate-float" :stroke-width="1.5" aria-hidden="true" />
      <p class="text-sm text-text-secondary mt-4">Start tracking your time</p>
      <p class="text-xs text-text-tertiary mt-2 max-w-xs text-center">Your dashboard will come alive with stats, charts, and recent activity once you start logging hours.</p>
      <router-link to="/timer" class="mt-4 px-4 py-2 bg-accent text-bg-base text-xs font-medium rounded-lg hover:bg-accent-hover transition-colors">
        Go to Timer
      </router-link>
    </div>

    <!-- Main content -->
    <Transition name="fade" appear>
    <div v-if="!loading && !isEmpty">
      <!-- Running timer indicator -->
      <div
        v-if="timerStore.timerState === 'RUNNING'"
        class="flex items-center gap-3 px-4 py-2.5 mb-4 bg-status-running/10 border border-status-running/20 rounded-lg"
        role="status"
        aria-live="polite"
      >
        <span class="relative flex h-2.5 w-2.5 shrink-0" aria-hidden="true">
          <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-status-running opacity-75" />
          <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-status-running" />
        </span>
        <div class="flex items-center gap-2 min-w-0 flex-1">
          <span class="text-[0.8125rem] font-medium text-text-primary">Now tracking</span>
          <div
            v-if="timerProjectColor"
            class="w-2 h-2 rounded-full shrink-0"
            :style="{ backgroundColor: timerProjectColor }"
            aria-hidden="true"
          />
          <span class="text-[0.75rem] text-text-secondary truncate">{{ timerProjectName }}</span>
          <span v-if="timerStore.description" class="text-[0.6875rem] text-text-tertiary truncate">- {{ timerStore.description }}</span>
        </div>
        <span class="text-[0.8125rem] font-mono text-status-running shrink-0">{{ formatDuration(timerStore.elapsedSeconds) }}</span>
      </div>

      <!-- Greeting header -->
      <div class="mb-6">
        <h1 class="text-xl font-[family-name:var(--font-heading)] text-text-secondary">{{ greeting }}</h1>
        <p class="text-xs text-text-tertiary mt-1">{{ formattedDate }}</p>
      </div>

      <!-- Stats row - 4 card columns -->
      <dl class="grid grid-cols-4 gap-4 mb-6">
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <dt class="text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1">Today</dt>
          <dd class="text-[1.25rem] font-[family-name:var(--font-heading)] text-accent-text font-medium">{{ formatDuration(todayStats.totalSeconds) }}</dd>
          <!-- Today's breakdown bar -->
          <div
            v-if="todayBreakdown.length > 0"
            class="flex w-full h-2 rounded-full overflow-hidden mt-2 gap-px"
            role="img"
            :aria-label="todayBreakdownLabel"
          >
            <div
              v-for="seg in todayBreakdown"
              :key="seg.projectId"
              class="h-full rounded-sm first:rounded-l-full last:rounded-r-full transition-all duration-300 relative group"
              :style="{ width: seg.percent + '%', backgroundColor: seg.color, minWidth: seg.percent > 0 ? '3px' : '0' }"
            >
              <div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 bg-bg-elevated border border-border-subtle rounded text-[0.625rem] text-text-primary whitespace-nowrap opacity-0 group-hover:opacity-100 pointer-events-none z-10 transition-opacity">
                {{ seg.name }} - {{ formatNumber(seg.hours, 1) }}h
              </div>
            </div>
          </div>
        </div>
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <dt class="text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1">This Week</dt>
          <dd class="text-[1.25rem] font-[family-name:var(--font-heading)] text-accent-text font-medium">{{ formatDuration(weekStats.totalSeconds) }}</dd>
          <div v-if="lastWeekSeconds > 0" class="flex items-center gap-1 mt-1">
            <span class="sr-only">Compared to last week:</span>
            <ChevronUp v-if="weekDiff > 0" class="w-3 h-3 text-status-running" aria-hidden="true" />
            <ChevronDown v-else-if="weekDiff < 0" class="w-3 h-3 text-status-error" aria-hidden="true" />
            <Minus v-else class="w-3 h-3 text-text-tertiary" aria-hidden="true" />
            <span class="text-[0.625rem]"
              :class="weekDiff >= 0 ? 'text-status-running' : 'text-status-error-text'">
              {{ formatDuration(Math.abs(weekDiff)) }} {{ weekDiff >= 0 ? 'more' : 'less' }}
            </span>
          </div>
        </div>
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <dt class="text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1">This Month</dt>
          <dd class="text-[1.25rem] font-[family-name:var(--font-heading)] text-accent-text font-medium">{{ formatDuration(monthStats.totalSeconds) }}</dd>
        </div>
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <dt class="text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1">Active Projects</dt>
          <dd class="text-[1.25rem] font-[family-name:var(--font-heading)] text-accent-text font-medium">{{ activeProjectsCount }}</dd>
        </div>
      </dl>

      <!-- Goal Progress -->
      <div v-if="goalProgress" class="bg-bg-surface border border-border-subtle rounded-lg p-4 mb-6">
        <h2 class="text-[0.8125rem] font-medium text-text-primary mb-3">Goals</h2>
        <div class="grid grid-cols-[1fr_1fr_auto] gap-4 items-center">
          <div>
            <div class="flex items-center justify-between mb-1.5">
              <span class="text-[0.75rem] text-text-secondary">Today</span>
              <span class="text-[0.75rem] font-mono text-accent-text">{{ formatGoalHours(goalProgress.today_seconds) }}</span>
            </div>
            <div class="w-full bg-bg-elevated rounded-full h-1.5" role="progressbar" :aria-valuenow="Math.round(dailyPct)" aria-valuemin="0" aria-valuemax="100" :aria-label="'Daily goal progress: ' + Math.round(dailyPct) + '%'">
              <div
                class="h-1.5 rounded-full bg-accent progress-bar"
                :style="{ width: Math.min(dailyPct, 100) + '%' }"
              />
            </div>
          </div>
          <div>
            <div class="flex items-center justify-between mb-1.5">
              <span class="text-[0.75rem] text-text-secondary">This Week</span>
              <span class="text-[0.75rem] font-mono text-accent-text">{{ formatGoalHours(goalProgress.week_seconds) }}</span>
            </div>
            <div class="w-full bg-bg-elevated rounded-full h-1.5" role="progressbar" :aria-valuenow="Math.round(weeklyPct)" aria-valuemin="0" aria-valuemax="100" :aria-label="'Weekly goal progress: ' + Math.round(weeklyPct) + '%'">
              <div
                class="h-1.5 rounded-full bg-accent progress-bar"
                :style="{ width: Math.min(weeklyPct, 100) + '%' }"
              />
            </div>
          </div>
          <div class="flex flex-col items-center px-3">
            <span class="text-[1.25rem] font-[family-name:var(--font-heading)] text-accent-text font-medium leading-none">{{ goalProgress.streak_days }}</span>
            <span class="text-[0.6875rem] text-text-tertiary mt-0.5">day streak</span>
          </div>
        </div>
      </div>

      <!-- Budget Alerts (full width, high visibility) -->
      <div v-if="budgetAlerts.length > 0" class="bg-bg-surface border border-border-subtle rounded-lg p-4 mb-6">
        <h2 class="text-[0.8125rem] font-medium text-text-primary mb-3">Budget Alerts</h2>
        <div class="grid grid-cols-2 gap-2">
          <div
            v-for="alert in budgetAlerts"
            :key="alert.id"
            class="flex items-center justify-between py-2 px-3 rounded-lg"
            :class="alert.pct > 90 ? 'bg-status-error/10' : 'bg-status-warning/10'"
          >
            <div class="flex items-center gap-2 min-w-0">
              <div class="w-2 h-2 rounded-full shrink-0" :style="{ backgroundColor: alert.color }" aria-hidden="true" />
              <span class="text-[0.75rem] text-text-primary truncate">{{ alert.name }}</span>
            </div>
            <span class="text-[0.75rem] font-mono shrink-0 ml-2" :class="alert.pct > 90 ? 'text-status-error-text' : 'text-status-warning'">
              {{ formatNumber(alert.pct, 0) }}%
            </span>
            <span class="sr-only">{{ alert.pct > 90 ? 'Over budget' : 'Approaching budget limit' }}</span>
          </div>
        </div>
      </div>

      <!-- 2x2 grid: charts + lists -->
      <div class="grid grid-cols-2 gap-4">

        <!-- Weekly chart -->
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <h2 class="text-[0.8125rem] font-medium text-text-primary mb-3">Weekly Hours</h2>
          <div class="h-44" aria-label="Weekly hours bar chart">
            <Bar v-if="chartData" :data="chartData" :options="chartOptions" />
          </div>
        </div>

        <!-- Recent entries -->
        <div class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <div class="flex items-center justify-between mb-3">
            <h2 class="text-[0.8125rem] font-medium text-text-primary">Recent Entries</h2>
            <router-link to="/entries" class="text-[0.6875rem] text-text-tertiary hover:text-text-secondary transition-colors" aria-label="View all time entries">View all</router-link>
          </div>

          <div v-if="recentEntries.length > 0" class="space-y-0">
            <div
              v-for="entry in recentEntries"
              :key="entry.id"
              class="group flex items-center justify-between py-2 border-b border-border-subtle last:border-0"
            >
              <div class="flex items-center gap-2 min-w-0">
                <div
                  class="w-2 h-2 rounded-full shrink-0"
                  :style="{ backgroundColor: getProjectColor(entry.project_id) }"
                  aria-hidden="true"
                />
                <span class="text-[0.75rem] text-text-primary truncate">{{ getProjectName(entry.project_id) }}</span>
              </div>
              <div class="flex items-center gap-1.5 shrink-0 ml-2">
                <button
                  @click="replayEntry(entry)"
                  class="p-1 text-text-tertiary hover:text-status-running transition-colors opacity-0 group-hover:opacity-100 focus:opacity-100"
                  aria-label="Start timer with this entry"
                  v-tooltip="'Replay entry'"
                >
                  <Play class="h-3 w-3" :stroke-width="2" fill="currentColor" aria-hidden="true" />
                </button>
                <span class="text-[0.75rem] font-mono text-text-secondary">{{ formatDuration(entry.duration) }}</span>
              </div>
            </div>
          </div>

          <p v-else class="text-[0.75rem] text-text-tertiary py-6 text-center">
            No entries yet. Start tracking your time.
          </p>
        </div>

        <!-- 4-week sparkline -->
        <div v-if="weeklySparkline.length > 0" class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <h2 class="text-[0.8125rem] font-medium text-text-primary mb-3">Last 4 Weeks</h2>
          <div class="flex items-end gap-3 h-16" role="img" :aria-label="sparklineLabel">
            <div
              v-for="(week, i) in weeklySparkline"
              :key="i"
              class="flex-1 flex flex-col items-center gap-1"
            >
              <div
                class="w-full rounded-sm transition-all duration-300"
                :class="i === weeklySparkline.length - 1 ? 'bg-accent' : 'bg-accent-muted'"
                :style="{ height: `${week.percent}%`, minHeight: week.hours > 0 ? '4px' : '0px' }"
              />
              <span class="text-[0.5625rem] text-text-tertiary">{{ week.label }}</span>
            </div>
          </div>
        </div>

        <!-- Project Forecasts -->
        <div v-if="projectForecasts.length > 0" class="bg-bg-surface border border-border-subtle rounded-lg p-4">
          <h2 class="text-[0.8125rem] font-medium text-text-primary mb-3">Project Forecasts</h2>
          <div class="space-y-3">
            <div
              v-for="forecast in projectForecasts"
              :key="forecast.id"
              class="px-3 py-2 bg-bg-base rounded-lg"
            >
              <div class="flex items-center justify-between mb-1">
                <div class="flex items-center gap-2 min-w-0">
                  <div class="w-2 h-2 rounded-full shrink-0" :style="{ backgroundColor: forecast.color }" aria-hidden="true" />
                  <span class="text-[0.75rem] text-text-primary truncate">{{ forecast.name }}</span>
                </div>
                <span class="text-[0.6875rem] font-mono shrink-0 ml-2" :class="paceColor(forecast.pace)">
                  {{ forecast.paceLabel }}
                </span>
              </div>
              <div class="flex items-center justify-between mb-1">
                <span class="text-[0.625rem] text-text-tertiary">{{ formatNumber(forecast.hoursUsed, 0) }}h / {{ forecast.budgetHours }}h</span>
                <span class="text-[0.625rem] text-text-tertiary">{{ formatNumber(forecast.dailyAvg, 1) }}h/day</span>
              </div>
              <div class="w-full bg-bg-elevated rounded-full h-1" role="progressbar" :aria-valuenow="Math.round(forecast.pct)" aria-valuemin="0" aria-valuemax="100" :aria-label="forecast.name + ' budget: ' + Math.round(forecast.pct) + '%'">
                <div
                  class="h-1 rounded-full progress-bar"
                  :class="forecast.pct > 90 ? 'bg-status-error' : forecast.pct > 75 ? 'bg-status-warning' : 'bg-accent'"
                  :style="{ width: Math.min(forecast.pct, 100) + '%' }"
                />
              </div>
            </div>
          </div>
        </div>

      </div>
    </div>
    </Transition>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import { Bar } from 'vue-chartjs'
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend
} from 'chart.js'
import { Clock, ChevronUp, ChevronDown, Minus, Play } from 'lucide-vue-next'
import { useRouter } from 'vue-router'
import { useToastStore } from '../stores/toast'
import GettingStartedChecklist from '../components/GettingStartedChecklist.vue'
import { useOnboardingStore } from '../stores/onboarding'
import { useEntriesStore } from '../stores/entries'
import { useProjectsStore } from '../stores/projects'
import { useSettingsStore } from '../stores/settings'
import { useTimerStore } from '../stores/timer'
import { formatDateLong, formatNumber } from '../utils/locale'
import { getChartTheme, buildBarChartOptions } from '../utils/chartTheme'
import type { TimeEntry } from '../stores/entries'

// Register Chart.js components
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend)

const entriesStore = useEntriesStore()
const projectsStore = useProjectsStore()
const settingsStore = useSettingsStore()
const onboardingStore = useOnboardingStore()
const timerStore = useTimerStore()
const router = useRouter()
const toastStore = useToastStore()

const loading = ref(true)

const goalProgress = ref<{ today_seconds: number; week_seconds: number; streak_days: number } | null>(null)

async function loadGoalProgress() {
  try {
    goalProgress.value = await invoke('get_goal_progress')
  } catch (e) {
    // ignore
  }
}

const dailyGoalHours = computed(() => parseFloat(settingsStore.settings.daily_goal_hours) || 8)
const weeklyGoalHours = computed(() => parseFloat(settingsStore.settings.weekly_goal_hours) || 40)
const dailyPct = computed(() => goalProgress.value ? (goalProgress.value.today_seconds / 3600 / dailyGoalHours.value) * 100 : 0)
const weeklyPct = computed(() => goalProgress.value ? (goalProgress.value.week_seconds / 3600 / weeklyGoalHours.value) * 100 : 0)

function formatGoalHours(seconds: number): string {
  const h = Math.floor(seconds / 3600)
  const m = Math.floor((seconds % 3600) / 60)
  return `${h}h ${m}m`
}

const todayStats = ref<{ totalSeconds: number; byProject: unknown[] }>({ totalSeconds: 0, byProject: [] })
const weekStats = ref<{ totalSeconds: number; byProject: unknown[] }>({ totalSeconds: 0, byProject: [] })
const monthStats = ref<{ totalSeconds: number; byProject: unknown[] }>({ totalSeconds: 0, byProject: [] })
const recentEntries = ref<TimeEntry[]>([])

// Weekly comparison data
const lastWeekSeconds = ref(0)
const weekDiff = ref(0)

// 4-week sparkline data
const weeklySparkline = ref<Array<{ hours: number; percent: number; label: string }>>([])
const sparklineLabel = computed(() =>
  weeklySparkline.value.map(w => `${w.label}: ${formatNumber(w.hours, 1)} hours`).join(', ')
)

// Greeting based on time of day
const greeting = computed(() => {
  const hour = new Date().getHours()
  if (hour < 12) return 'Good morning'
  if (hour < 18) return 'Good afternoon'
  return 'Good evening'
})

// Formatted date
const formattedDate = computed(() => {
  return formatDateLong(new Date().toISOString())
})

// Empty state check
const isEmpty = computed(() => {
  return recentEntries.value.length === 0 && weekStats.value.totalSeconds === 0
})

// Get start of current week (Monday)
function getWeekStart(): string {
  const now = new Date()
  const day = now.getDay()
  const diff = now.getDate() - day + (day === 0 ? -6 : 1)
  const monday = new Date(now.setDate(diff))
  return monday.toISOString().split('T')[0]
}

// Get start of current month
function getMonthStart(): string {
  const now = new Date()
  return new Date(now.getFullYear(), now.getMonth(), 1).toISOString().split('T')[0]
}

// Get today's date
function getToday(): string {
  return new Date().toISOString().split('T')[0]
}

// Format a Date to YYYY-MM-DD
function formatDate(d: Date): string {
  return d.toISOString().split('T')[0]
}

// Format duration from seconds to readable format
function formatDuration(seconds: number): string {
  const hours = Math.floor(seconds / 3600)
  const minutes = Math.floor((seconds % 3600) / 60)
  if (hours > 0) {
    return `${hours}h ${minutes}m`
  }
  return `${minutes}m`
}

function replayEntry(entry: TimeEntry) {
  if (!timerStore.isStopped) {
    toastStore.info('Timer is already running. Stop it first.')
    return
  }
  timerStore.setProject(entry.project_id)
  timerStore.setTask(entry.task_id || null)
  timerStore.setDescription(entry.description || '')
  timerStore.setBillable(entry.billable ?? 1)
  timerStore.start()
  router.push('/timer')
}

// Get project name by ID
function getProjectName(projectId: number): string {
  const project = projectsStore.projects.find(p => p.id === projectId)
  return project?.name || 'Unknown Project'
}

// Get project color by ID
function getProjectColor(projectId: number): string {
  const project = projectsStore.projects.find(p => p.id === projectId)
  return project?.color || '#6B7280'
}

// Active projects count (non-archived)
const activeProjectsCount = computed(() => {
  return projectsStore.projects.filter(p => !p.archived).length
})

// Running timer helpers
const timerProjectName = computed(() => {
  if (!timerStore.selectedProjectId) return ''
  return getProjectName(timerStore.selectedProjectId)
})
const timerProjectColor = computed(() => {
  if (!timerStore.selectedProjectId) return ''
  return getProjectColor(timerStore.selectedProjectId)
})

// Today's breakdown - stacked bar showing time by project
interface BreakdownSegment {
  projectId: number
  name: string
  color: string
  seconds: number
  hours: number
  percent: number
}

const todayBreakdown = computed<BreakdownSegment[]>(() => {
  const byProject = todayStats.value.byProject as Array<{ project_id: number; total_seconds: number }> | undefined
  if (!byProject || byProject.length === 0) return []
  const total = todayStats.value.totalSeconds
  if (total <= 0) return []
  return byProject.map(bp => {
    const p = projectsStore.projects.find(proj => proj.id === bp.project_id)
    return {
      projectId: bp.project_id,
      name: p?.name || 'Unknown',
      color: p?.color || '#6B7280',
      seconds: bp.total_seconds,
      hours: bp.total_seconds / 3600,
      percent: (bp.total_seconds / total) * 100,
    }
  }).filter(s => s.percent > 0)
})

const todayBreakdownLabel = computed(() =>
  todayBreakdown.value.map(s => `${s.name}: ${formatNumber(s.hours, 1)} hours`).join(', ')
)

// Budget status
interface DashboardBudgetStatus {
  hours_used: number
  amount_used: number
  daily_average_hours: number
  estimated_completion_days: number | null
  hours_remaining: number | null
  pace: string | null
}

const budgetStatus = ref<Record<number, DashboardBudgetStatus>>({})

async function loadBudgetStatus() {
  for (const project of projectsStore.projects) {
    if (project.id && project.budget_hours) {
      try {
        const today = new Date().toISOString().split('T')[0]
        const status = await invoke<DashboardBudgetStatus>('get_project_budget_status', { projectId: project.id, today })
        budgetStatus.value[project.id] = status
      } catch (e) {
        // ignore
      }
    }
  }
}

const budgetAlerts = computed(() => {
  return projectsStore.projects
    .filter(p => p.id && p.budget_hours)
    .map(p => {
      const used = budgetStatus.value[p.id!]?.hours_used || 0
      const pct = (used / p.budget_hours!) * 100
      return { id: p.id!, name: p.name, color: p.color, pct }
    })
    .filter(a => a.pct > 75)
    .sort((a, b) => b.pct - a.pct)
})

// Project forecasts
interface ForecastData {
  id: number
  name: string
  color: string
  hoursUsed: number
  budgetHours: number
  pct: number
  dailyAvg: number
  pace: string | null
  paceLabel: string
}

const projectForecasts = computed<ForecastData[]>(() => {
  return projectsStore.projects
    .filter(p => p.id && p.budget_hours && budgetStatus.value[p.id!])
    .map(p => {
      const status = budgetStatus.value[p.id!]
      const pct = p.budget_hours! > 0 ? (status.hours_used / p.budget_hours!) * 100 : 0
      let paceLabel = 'No data'
      if (status.pace === 'ahead') paceLabel = 'Ahead'
      else if (status.pace === 'on_track') paceLabel = 'On track'
      else if (status.pace === 'behind') paceLabel = 'Behind'
      else if (status.pace === 'complete') paceLabel = 'Complete'
      return {
        id: p.id!,
        name: p.name,
        color: p.color,
        hoursUsed: status.hours_used,
        budgetHours: p.budget_hours!,
        pct,
        dailyAvg: status.daily_average_hours || 0,
        pace: status.pace,
        paceLabel,
      }
    })
    .slice(0, 5)
})

function paceColor(pace: string | null): string {
  if (pace === 'ahead') return 'text-status-running'
  if (pace === 'on_track') return 'text-accent-text'
  if (pace === 'behind') return 'text-status-error-text'
  if (pace === 'complete') return 'text-status-running'
  return 'text-text-tertiary'
}

// Chart theme state
const chartTheme = ref(getChartTheme())

function refreshChartTheme() {
  chartTheme.value = getChartTheme()
}

// Chart data for weekly hours
const chartData = computed(() => {
  const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  const weekStart = getWeekStart()
  const today = getToday()
  const todayIndex = new Date().getDay()
  const todayArrayIndex = todayIndex === 0 ? 6 : todayIndex - 1

  // Initialize hours for each day
  const hoursPerDay = [0, 0, 0, 0, 0, 0, 0]

  // Sum up hours from entries for this week
  recentEntries.value.forEach(entry => {
    const entryDate = new Date(entry.start_time).toISOString().split('T')[0]
    if (entryDate >= weekStart && entryDate <= today) {
      const dayIndex = new Date(entry.start_time).getDay()
      const index = dayIndex === 0 ? 6 : dayIndex - 1
      hoursPerDay[index] += entry.duration / 3600
    }
  })

  const theme = chartTheme.value
  const colors = hoursPerDay.map((_, i) => i === todayArrayIndex ? (theme.accentMuted || theme.accent) : theme.accent)

  return {
    labels: days,
    datasets: [
      {
        label: 'Hours',
        data: hoursPerDay,
        backgroundColor: colors,
        borderRadius: 2
      }
    ]
  }
})

// Chart options (theme-aware)
const chartOptions = computed(() => {
  const theme = chartTheme.value
  const base = buildBarChartOptions(theme)
  return {
    ...base,
    scales: {
      ...base.scales,
      y: {
        ...base.scales.y,
        beginAtZero: true,
      },
    },
    plugins: {
      ...base.plugins,
      tooltip: {
        ...base.plugins.tooltip,
        callbacks: {
          label: (context: { raw: unknown }) => {
            const hours = context.raw as number
            return `${formatNumber(hours, 1)} hours`
          }
        }
      }
    }
  }
})

// Recreate chart on theme or accent change
watch(() => settingsStore.settings.theme_mode, () => {
  nextTick(() => { refreshChartTheme() })
})
watch(() => settingsStore.settings.accent_color, () => {
  nextTick(() => { refreshChartTheme() })
})

// Load data on mount
onMounted(async () => {
  loading.value = true

  await Promise.all([
    projectsStore.fetchProjects(),
    entriesStore.fetchEntries(),
    settingsStore.fetchSettings(),
    loadGoalProgress(),
  ])

  // Budget status depends on projects being loaded
  await loadBudgetStatus()

  // Fetch stats in parallel
  const [todayResult, weekResult, monthResult] = await Promise.allSettled([
    invoke<{ totalSeconds: number; byProject: unknown[] }>('get_reports', {
      startDate: getToday(),
      endDate: getToday()
    }),
    invoke<{ totalSeconds: number; byProject: unknown[] }>('get_reports', {
      startDate: getWeekStart(),
      endDate: getToday()
    }),
    invoke<{ totalSeconds: number; byProject: unknown[] }>('get_reports', {
      startDate: getMonthStart(),
      endDate: getToday()
    }),
  ])

  if (todayResult.status === 'fulfilled') todayStats.value = todayResult.value
  if (weekResult.status === 'fulfilled') weekStats.value = weekResult.value
  if (monthResult.status === 'fulfilled') monthStats.value = monthResult.value

  recentEntries.value = entriesStore.entries.slice(0, 5)

  // Fetch last week's data for comparison
  const lastWeekEnd = new Date()
  lastWeekEnd.setDate(lastWeekEnd.getDate() - lastWeekEnd.getDay() + (lastWeekEnd.getDay() === 0 ? -7 : 0))
  const lastWeekStart = new Date(lastWeekEnd)
  lastWeekStart.setDate(lastWeekStart.getDate() - 6)
  try {
    const lastWeek = await invoke<{ totalSeconds: number; byProject: unknown[] }>('get_reports', {
      startDate: formatDate(lastWeekStart),
      endDate: formatDate(lastWeekEnd)
    })
    lastWeekSeconds.value = lastWeek.totalSeconds || 0
    weekDiff.value = weekStats.value.totalSeconds - lastWeekSeconds.value
  } catch {
    // Comparison data is optional
  }

  // Fetch sparkline data for last 4 weeks (including current)
  const sparklineData: Array<{ hours: number; label: string }> = []
  for (let w = 3; w >= 0; w--) {
    const now = new Date()
    const dayOfWeek = now.getDay()
    const monday = new Date(now)
    monday.setDate(now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) - (w * 7))
    const sunday = new Date(monday)
    sunday.setDate(sunday.getDate() + 6)
    const end = w === 0 ? now : sunday
    try {
      const report = await invoke<{ totalSeconds: number; byProject: unknown[] }>('get_reports', {
        startDate: formatDate(monday),
        endDate: formatDate(end)
      })
      sparklineData.push({
        hours: (report.totalSeconds || 0) / 3600,
        label: `${monday.getDate()}/${monday.getMonth() + 1}`
      })
    } catch {
      sparklineData.push({ hours: 0, label: `${monday.getDate()}/${monday.getMonth() + 1}` })
    }
  }
  const maxHours = Math.max(...sparklineData.map(d => d.hours), 1)
  weeklySparkline.value = sparklineData.map(d => ({
    hours: d.hours,
    percent: (d.hours / maxHours) * 100,
    label: d.label
  }))

  await onboardingStore.load()

  // Refresh chart theme after settings are loaded
  refreshChartTheme()

  loading.value = false
})
</script>
