<template>
  <div class="p-6 grid grid-cols-1 lg:grid-cols-[1fr_280px] lg:gap-8 lg:items-start">
    <!-- Left column -->
    <div class="w-full max-w-[38rem] mx-auto">
      <h1 class="sr-only">Timer</h1>
      <!-- Sticky timer hero -->
      <div class="sticky top-0 z-10 bg-bg-base pb-2">
        <div class="text-center pt-4 pb-8">
          <div class="relative inline-block">
            <p class="text-[3.5rem] font-medium font-[family-name:var(--font-timer)] tracking-tighter mb-2 transition-colors duration-300" :class="[timerPulseClass, timerStore.isPaused ? 'opacity-60' : '']" role="timer" aria-live="off" :aria-label="'Elapsed time: ' + timerStore.formattedTime">
              <span :class="timerStore.isPaused ? 'text-text-tertiary' : 'text-text-primary'">{{ timerParts.hours }}</span>
              <span aria-hidden="true" :class="timerStore.isRunning ? 'text-accent-text animate-pulse-colon' : timerStore.isPaused ? 'text-text-tertiary' : 'text-text-primary'">:</span>
              <span :class="timerStore.isPaused ? 'text-text-tertiary' : 'text-text-primary'">{{ timerParts.minutes }}</span>
              <span aria-hidden="true" :class="timerStore.isRunning ? 'text-accent-text animate-pulse-colon' : timerStore.isPaused ? 'text-text-tertiary' : 'text-text-primary'">:</span>
              <span :class="timerStore.isPaused ? 'text-text-tertiary' : 'text-text-primary'">{{ timerParts.seconds }}</span>
            </p>
            <!-- Paused badge - absolutely positioned so it doesn't shift layout -->
            <span
              v-if="timerStore.isPaused"
              role="status"
              class="absolute -bottom-1 left-1/2 -translate-x-1/2 text-[0.625rem] font-semibold uppercase tracking-[0.15em] px-2.5 py-0.5 rounded-full transition-opacity duration-200"
              :class="timerStore.timerState === 'PAUSED_IDLE' ? 'text-status-warning bg-status-warning/10' : timerStore.timerState === 'PAUSED_MANUAL' ? 'text-status-warning bg-status-warning/10' : 'text-status-info bg-status-info/10'"
            >
              {{ timerStore.timerState === 'PAUSED_IDLE' ? 'Idle' : timerStore.timerState === 'PAUSED_MANUAL' ? 'Paused' : 'App hidden' }}
            </span>
            <button
              v-if="!timerStore.isStopped"
              @click="openMiniTimer"
              class="absolute -right-8 top-1/2 -translate-y-1/2 p-2 text-text-tertiary hover:text-text-secondary transition-colors"
              aria-label="Pop out mini timer"
              v-tooltip="'Pop out mini timer'"
            >
              <ExternalLink class="w-4 h-4" :stroke-width="1.5" aria-hidden="true" />
            </button>
          </div>

          <div class="h-6" />

          <div class="flex items-center justify-center gap-3">
            <!-- Pause / Resume button (visible when timer is active) -->
            <button
              v-if="timerStore.isRunning"
              @click="timerStore.pauseManual()"
              class="px-6 py-3 text-sm font-medium rounded-lg transition-colors duration-150 bg-status-warning/15 text-status-warning hover:bg-status-warning/25"
            >
              Pause
            </button>
            <button
              v-else-if="timerStore.timerState === 'PAUSED_MANUAL'"
              @click="timerStore.resumeFromPause()"
              class="px-6 py-3 text-sm font-medium rounded-lg transition-colors duration-150 bg-accent text-bg-base hover:bg-accent-hover"
            >
              Resume
            </button>

            <!-- Quick-switch button -->
            <button
              v-if="!timerStore.isStopped"
              @click="showSwitchPicker = !showSwitchPicker"
              class="px-4 py-3 text-sm font-medium rounded-lg transition-colors duration-150 border border-border-subtle text-text-secondary hover:text-text-primary hover:bg-bg-elevated"
              aria-label="Switch project"
              v-tooltip="'Switch project'"
            >
              <ArrowLeftRight class="w-4 h-4" :stroke-width="1.5" aria-hidden="true" />
            </button>

            <!-- Start / Stop button -->
            <button
              data-tour-id="timer-start"
              @click="toggleTimer"
              class="btn-primary px-10 py-3 text-sm font-medium rounded-lg transition-colors duration-150"
              :class="buttonClass"
            >
              {{ buttonLabel }}
            </button>
          </div>
          <!-- Quick-switch project picker -->
          <div v-if="showSwitchPicker" class="mt-3 max-w-xs mx-auto">
            <AppSelect
              :model-value="null"
              :options="projectsStore.activeProjects"
              label-key="name"
              value-key="id"
              placeholder="Switch to project..."
              searchable
              @update:model-value="switchToProject($event)"
            />
          </div>
        </div>
      </div>

      <!-- Favorites strip -->
      <div v-if="favorites.length > 0" class="mb-4">
        <div class="flex flex-wrap items-center gap-y-2" @pointerleave="onFavDragCancel">
          <template v-for="(fav, favIndex) in favorites" :key="fav.id">
            <!-- Drop indicator / spacer before each chip -->
            <div
              class="transition-all duration-150 self-stretch flex items-center justify-center"
              :class="dragFavIndex !== null && dropTargetIndex === favIndex && dragFavIndex !== favIndex
                ? 'w-3'
                : 'w-1.5'"
              @pointerenter="onFavDragOver(favIndex)"
              @pointerup="onFavDragEnd"
            >
              <div
                class="w-0.5 h-5 rounded-full transition-opacity duration-150"
                :class="dragFavIndex !== null && dropTargetIndex === favIndex && dragFavIndex !== favIndex
                  ? 'bg-accent opacity-100 shadow-[0_0_6px_var(--color-accent)]'
                  : 'opacity-0'"
              />
            </div>
            <!-- Chip -->
            <div
              class="flex items-center rounded-full border border-border-subtle text-[0.6875rem] text-text-secondary hover:text-text-primary hover:border-border-visible transition-colors"
              :class="[
                dragFavIndex === favIndex ? 'opacity-40' : '',
                dragFavIndex !== null && dragFavIndex !== favIndex ? 'cursor-grabbing' : 'cursor-grab'
              ]"
              @pointerdown.prevent="onFavDragStart(favIndex)"
              @pointerenter="onFavDragOver(favIndex)"
              @pointerup="onFavDragEnd"
              @keydown.ctrl.left.prevent="moveFavorite(favIndex, -1)"
              @keydown.ctrl.right.prevent="moveFavorite(favIndex, 1)"
            >
              <span class="flex items-center gap-1.5 pl-2.5 py-1.5 select-none">
                <span class="w-2 h-2 rounded-full shrink-0" :style="{ backgroundColor: getProjectColor(fav.project_id) }" aria-hidden="true" />
                {{ getProjectName(fav.project_id) }}
                <span v-if="fav.description" class="text-text-tertiary">&middot; {{ fav.description }}</span>
              </span>
              <button
                @click.stop="applyFavorite(fav)"
                :disabled="!timerStore.isStopped"
                class="flex items-center justify-center w-6 h-6 rounded-full text-text-tertiary hover:text-accent disabled:opacity-40 cursor-pointer"
                aria-label="Load fields"
                v-tooltip="'Load fields'"
              >
                <ArrowDownToLine class="w-3 h-3" :stroke-width="2" aria-hidden="true" />
              </button>
              <button
                @click.stop="quickStartFavorite(fav)"
                :disabled="!timerStore.isStopped"
                class="flex items-center justify-center w-6 h-6 rounded-full text-accent hover:text-accent-hover disabled:opacity-40 cursor-pointer"
                aria-label="Start timer"
                v-tooltip="'Start timer'"
              >
                <Play class="w-3 h-3" :stroke-width="2" fill="currentColor" aria-hidden="true" />
              </button>
              <button
                @click.stop="removeFavorite(fav.id!)"
                class="flex items-center justify-center w-5 h-5 mr-1 rounded-full text-text-tertiary hover:text-status-error cursor-pointer"
                aria-label="Delete favorite"
                v-tooltip="'Delete favorite'"
              >
                <X class="w-3 h-3" :stroke-width="2" aria-hidden="true" />
              </button>
            </div>
          </template>
          <!-- Drop indicator after last chip -->
          <div
            class="transition-all duration-150 self-stretch flex items-center justify-center"
            :class="dragFavIndex !== null && dropTargetIndex === favorites.length
              ? 'w-3'
              : 'w-0'"
            @pointerenter="onFavDragOver(favorites.length)"
            @pointerup="onFavDragEnd"
          >
            <div
              class="w-0.5 h-5 rounded-full transition-opacity duration-150"
              :class="dragFavIndex !== null && dropTargetIndex === favorites.length
                ? 'bg-accent opacity-100 shadow-[0_0_6px_var(--color-accent)]'
                : 'opacity-0'"
            />
          </div>
        </div>
      </div>

      <!-- Inputs -->
      <div class="mb-8">
        <div class="grid grid-cols-2 gap-4 mb-4">
          <div data-tour-id="timer-project">
            <label id="label-timer-project" class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Project</label>
            <AppSelect
              v-model="selectedProject"
              aria-labelledby="label-timer-project"
              :options="activeProjects"
              label-key="name"
              value-key="id"
              placeholder="Select project"
              :placeholder-value="null"
              :disabled="!timerStore.isStopped"
            />
          </div>
          <div>
            <label id="label-timer-task" class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Task</label>
            <AppSelect
              v-model="selectedTask"
              aria-labelledby="label-timer-task"
              :options="projectTasks"
              label-key="name"
              value-key="id"
              placeholder="Select task"
              :placeholder-value="null"
              :disabled="!timerStore.isStopped || !selectedProject"
            />
          </div>
        </div>
        <!-- Budget progress indicator -->
        <div v-if="projectBudgetStatus" class="mt-1.5">
          <div class="flex items-center justify-between mb-0.5">
            <span class="text-[0.5625rem] text-text-tertiary">{{ formatNumber(projectBudgetStatus.hoursUsed, 0) }}h / {{ projectBudgetStatus.budgetHours }}h</span>
            <span class="text-[0.5625rem]" :class="projectBudgetStatus.pct > 90 ? 'text-status-error-text' : projectBudgetStatus.pct > 75 ? 'text-status-warning' : 'text-text-tertiary'">{{ formatNumber(projectBudgetStatus.pct, 0) }}%</span>
          </div>
          <div class="w-full bg-bg-elevated rounded-full h-0.5">
            <div
              class="h-0.5 rounded-full progress-bar"
              :class="projectBudgetStatus.pct > 90 ? 'bg-status-error' : projectBudgetStatus.pct > 75 ? 'bg-status-warning' : 'bg-accent'"
              :style="{ width: Math.min(projectBudgetStatus.pct, 100) + '%' }"
            />
          </div>
        </div>
        <div data-tour-id="timer-description">
          <label for="timer-description" class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Description</label>
          <div class="flex gap-2">
            <div class="flex-1 relative">
              <input
                id="timer-description"
                v-model="description"
                type="text"
                :disabled="!timerStore.isStopped"
                class="w-full px-3 py-2 bg-bg-inset border border-border-subtle rounded-lg text-[0.8125rem] text-text-primary placeholder-text-tertiary focus:outline-none focus:border-border-visible disabled:opacity-40 disabled:cursor-not-allowed"
                placeholder="What are you working on?"
                role="combobox"
                aria-autocomplete="list"
                :aria-expanded="showDescSuggestions"
                aria-controls="desc-suggestions"
                :aria-activedescendant="activeDescIndex >= 0 ? 'desc-opt-' + activeDescIndex : undefined"
                @focus="onDescFocus"
                @blur="onDescBlur"
                @keydown="onDescKeydown"
                autocomplete="off"
              />
              <ul
                v-if="showDescSuggestions && filteredDescriptions.length > 0"
                id="desc-suggestions"
                role="listbox"
                class="absolute z-20 left-0 right-0 top-full mt-1 max-h-48 overflow-y-auto bg-bg-elevated border border-border-subtle rounded-lg shadow-lg"
              >
                <li
                  v-for="(desc, i) in filteredDescriptions"
                  :id="'desc-opt-' + i"
                  :key="desc"
                  role="option"
                  :aria-selected="i === activeDescIndex"
                  class="px-3 py-2 text-[0.8125rem] text-text-primary cursor-pointer transition-colors"
                  :class="i === activeDescIndex ? 'bg-accent/10 text-accent-text' : 'hover:bg-bg-surface'"
                  @mousedown.prevent="selectDescription(desc)"
                >
                  {{ desc }}
                </li>
              </ul>
            </div>
            <button
              @click="timerStore.setBillable(timerStore.billable === 1 ? 0 : 1)"
              :aria-label="timerStore.billable === 1 ? 'Mark as non-billable' : 'Mark as billable'"
              v-tooltip="'Toggle billable'"
              class="w-8 h-8 flex items-center justify-center rounded-full transition-colors"
              :class="timerStore.billable === 1
                ? 'bg-accent-muted text-accent-text'
                : 'bg-bg-elevated text-text-tertiary'"
            >
              <DollarSign class="w-4 h-4" aria-hidden="true" />
            </button>
            <button
              v-if="timerStore.isStopped && selectedProject"
              @click="saveAsFavorite"
              class="p-2 text-text-tertiary hover:text-accent-text transition-colors"
              aria-label="Save as favorite"
              v-tooltip="'Save as favorite'"
            >
              <Star class="w-4 h-4" :stroke-width="1.5" aria-hidden="true" />
            </button>
          </div>
        </div>
        <div class="mt-3">
          <label for="timer-tags" class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Tags</label>
          <AppTagInput v-model="selectedTags" />
        </div>
      </div>

      <!-- Timeline Panel -->
      <div v-if="timelineEnabled" class="mb-8 border border-border-subtle rounded-lg overflow-hidden">
        <button
          type="button"
          @click="toggleTimelinePanel"
          class="w-full flex items-center justify-between px-3 py-2.5 text-[0.8125rem] text-text-primary hover:bg-bg-elevated transition-colors"
        >
          <span>Timeline</span>
          <ChevronDown
            class="w-4 h-4 text-text-tertiary transition-transform duration-200"
            :class="{ 'rotate-180': timelineExpanded }"
            :stroke-width="1.5"
            aria-hidden="true"
          />
        </button>
        <div v-if="timelineExpanded" class="border-t border-border-subtle px-3 py-3">
          <div v-if="timelineEvents.length > 0">
            <!-- Timeline bar -->
            <div class="relative w-full h-8 bg-bg-inset rounded overflow-hidden mb-2">
              <div
                v-for="seg in timelineSegments"
                :key="seg.id"
                class="absolute top-0 h-full rounded-sm cursor-default transition-opacity hover:opacity-80"
                :style="{
                  left: seg.left + '%',
                  width: Math.max(seg.width, 0.3) + '%',
                  backgroundColor: seg.color,
                }"
                role="img"
                :aria-label="seg.tooltip"
              />
            </div>
            <!-- Time labels -->
            <div class="flex justify-between text-[0.5625rem] text-text-tertiary mb-3">
              <span>{{ timelineStartLabel }}</span>
              <span>{{ timelineEndLabel }}</span>
            </div>
            <!-- Legend -->
            <div class="flex flex-wrap gap-x-3 gap-y-1 mb-3">
              <div v-for="app in timelineApps" :key="app.name" class="flex items-center gap-1.5">
                <span class="w-2 h-2 rounded-sm shrink-0" :style="{ backgroundColor: app.color }" />
                <span class="text-[0.625rem] text-text-secondary truncate max-w-[120px]">{{ app.name }}</span>
              </div>
            </div>
            <button
              @click="clearTodayTimeline"
              class="flex items-center gap-1.5 text-[0.6875rem] text-text-tertiary hover:text-status-error transition-colors"
            >
              <Trash2 class="w-3 h-3" :stroke-width="1.5" aria-hidden="true" />
              Clear today
            </button>
          </div>
          <p v-else class="text-[0.6875rem] text-text-tertiary">No timeline events recorded today. Events appear as the timer runs.</p>
        </div>
      </div>
    </div>

    <!-- Right column -->
    <div class="lg:sticky lg:top-6">
      <div class="flex items-center justify-between mb-3">
        <h2 class="text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em]">Recent</h2>
        <router-link v-if="recentEntries.length > 0" to="/entries" class="text-xs text-text-tertiary hover:text-text-secondary transition-colors" aria-label="View all time entries">View all</router-link>
      </div>

      <TransitionGroup v-if="recentEntries.length > 0" name="list" tag="div">
        <div
          v-for="(entry, index) in recentEntries"
          :key="entry.id"
          class="flex items-center justify-between py-3 border-b border-border-subtle last:border-0"
          :class="index === 0 ? 'border-l-2 border-l-accent pl-3' : ''"
          :style="{ transitionDelay: `${index * 40}ms` }"
        >
          <div class="flex items-center gap-3 min-w-0">
            <div
              class="w-2 h-2 rounded-full shrink-0"
              :style="{ backgroundColor: getProjectColor(entry.project_id) }"
              aria-hidden="true"
            />
            <div class="min-w-0">
              <p class="text-[0.75rem] text-text-primary truncate">{{ getProjectName(entry.project_id) }}</p>
              <p class="text-[0.6875rem] text-text-tertiary truncate">{{ entry.description || 'No description' }}</p>
            </div>
          </div>
          <div class="flex items-center gap-2 shrink-0">
            <div class="text-right">
              <p class="text-[0.75rem] font-mono text-text-primary">{{ formatDuration(entry.duration) }}</p>
              <p class="text-[0.6875rem] text-text-tertiary">{{ formatDateTime(entry.start_time) }}</p>
            </div>
            <button
              v-if="timerStore.isStopped"
              @click="repeatEntry(entry)"
              class="p-1 text-text-tertiary hover:text-text-secondary transition-colors"
              aria-label="Repeat entry"
              v-tooltip="'Replay entry'"
            >
              <RotateCcw class="w-3 h-3" :stroke-width="2" aria-hidden="true" />
            </button>
          </div>
        </div>
      </TransitionGroup>

      <!-- Empty state -->
      <div v-else class="flex flex-col items-center py-8">
        <TimerIcon class="w-10 h-10 text-text-tertiary animate-float" :stroke-width="1.5" aria-hidden="true" />
        <p class="text-sm text-text-secondary mt-3">No entries today</p>
        <p class="text-xs text-text-tertiary mt-1">Select a project and hit Start to begin tracking</p>
      </div>
    </div>

    <!-- Idle Prompt Dialog -->
    <IdlePromptDialog
      :show="timerStore.showIdlePrompt"
      :idle-seconds="timerStore.idleDurationSeconds"
      @continue-keep="onIdleContinueKeep"
      @continue-subtract="onIdleContinueSubtract"
      @stop-timer="onIdleStop"
    />

    <!-- App Tracking Prompt Dialog -->
    <AppTrackingPromptDialog
      :show="timerStore.showAppPrompt"
      @continue-timer="onAppContinue"
      @stop-timer="onAppStop"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { useTimerStore } from '../stores/timer'
import { useProjectsStore, type Task } from '../stores/projects'
import { useEntriesStore } from '../stores/entries'
import { useSettingsStore } from '../stores/settings'
import { useToastStore } from '../stores/toast'
import { Timer as TimerIcon, RotateCcw, ExternalLink, Star, DollarSign, ChevronDown, Trash2, Play, ArrowLeftRight, X, ArrowDownToLine } from 'lucide-vue-next'
import { invoke } from '@tauri-apps/api/core'
import AppSelect from '../components/AppSelect.vue'
import AppTagInput from '../components/AppTagInput.vue'
import IdlePromptDialog from '../components/IdlePromptDialog.vue'
import AppTrackingPromptDialog from '../components/AppTrackingPromptDialog.vue'
import { formatDateTime, formatNumber } from '../utils/locale'
import { useFavoritesStore, type Favorite } from '../stores/favorites'
import { useTagsStore } from '../stores/tags'

const timerStore = useTimerStore()
const projectsStore = useProjectsStore()
const entriesStore = useEntriesStore()
const settingsStore = useSettingsStore()
const toastStore = useToastStore()
const favoritesStore = useFavoritesStore()
const tagsStore = useTagsStore()
const favorites = computed(() => favoritesStore.favorites)

// Local state for inputs
const selectedProject = ref<number | null>(timerStore.selectedProjectId)
const selectedTask = ref<number | null>(timerStore.selectedTaskId)
const description = ref(timerStore.description)
const recentDescriptions = ref<string[]>([])
const showDescSuggestions = ref(false)
const activeDescIndex = ref(-1)

const filteredDescriptions = computed(() => {
  const q = description.value.toLowerCase().trim()
  if (q.length < 2) return recentDescriptions.value.slice(0, 10)
  return recentDescriptions.value.filter(d => d.toLowerCase().includes(q)).slice(0, 10)
})

async function loadRecentDescriptions() {
  try {
    recentDescriptions.value = await invoke<string[]>('get_recent_descriptions')
  } catch { /* ignore */ }
}

function onDescFocus() {
  if (recentDescriptions.value.length > 0 && timerStore.isStopped) {
    showDescSuggestions.value = true
    activeDescIndex.value = -1
  }
}

function onDescBlur() {
  // Delay so mousedown on option fires first
  setTimeout(() => { showDescSuggestions.value = false }, 150)
}

function onDescKeydown(e: KeyboardEvent) {
  if (!showDescSuggestions.value || filteredDescriptions.value.length === 0) return
  if (e.key === 'ArrowDown') {
    e.preventDefault()
    activeDescIndex.value = Math.min(activeDescIndex.value + 1, filteredDescriptions.value.length - 1)
  } else if (e.key === 'ArrowUp') {
    e.preventDefault()
    activeDescIndex.value = Math.max(activeDescIndex.value - 1, -1)
  } else if (e.key === 'Enter' && activeDescIndex.value >= 0) {
    e.preventDefault()
    selectDescription(filteredDescriptions.value[activeDescIndex.value])
  } else if (e.key === 'Escape') {
    showDescSuggestions.value = false
  }
}

function selectDescription(desc: string) {
  description.value = desc
  showDescSuggestions.value = false
  activeDescIndex.value = -1
}

const selectedTags = ref<number[]>([])
const projectTasks = ref<Task[]>([])
const projectBudgetStatus = ref<{ hoursUsed: number; budgetHours: number; pct: number } | null>(null)
const timerPulseClass = ref('')

// Timeline state
interface TimelineEvent {
  id: number
  project_id: number
  exe_name: string | null
  exe_path: string | null
  window_title: string | null
  started_at: string
  ended_at: string | null
  duration: number | null
}

const timelineExpanded = ref(false)
const timelineEvents = ref<TimelineEvent[]>([])

const timelineEnabled = computed(() => {
  const globalOn = settingsStore.settings.timeline_recording === 'on'
  if (selectedProject.value) {
    const project = projectsStore.projects.find(p => p.id === selectedProject.value)
    if (project?.timeline_override === 'on') return true
    if (project?.timeline_override === 'off') return false
  }
  return globalOn
})

function hashColor(str: string): string {
  let hash = 0
  for (let i = 0; i < str.length; i++) {
    hash = str.charCodeAt(i) + ((hash << 5) - hash)
  }
  const hue = Math.abs(hash) % 360
  return `hsl(${hue}, 55%, 50%)`
}

const timelineSegments = computed(() => {
  if (timelineEvents.value.length === 0) return []
  const events = timelineEvents.value
  const firstStart = new Date(events[0].started_at).getTime()
  const lastEnd = events.reduce((max, e) => {
    const end = e.ended_at ? new Date(e.ended_at).getTime() : Date.now()
    return Math.max(max, end)
  }, firstStart)
  const totalSpan = lastEnd - firstStart
  if (totalSpan <= 0) return []
  return events.map(e => {
    const start = new Date(e.started_at).getTime()
    const end = e.ended_at ? new Date(e.ended_at).getTime() : Date.now()
    const left = ((start - firstStart) / totalSpan) * 100
    const width = ((end - start) / totalSpan) * 100
    const appName = e.exe_name || 'Unknown'
    const dur = e.duration ?? Math.floor((end - start) / 1000)
    const durMin = Math.floor(dur / 60)
    const durSec = dur % 60
    const timeRange = formatTimeHM(e.started_at) + ' - ' + (e.ended_at ? formatTimeHM(e.ended_at) : 'now')
    return {
      id: e.id,
      left,
      width,
      color: hashColor(appName),
      tooltip: `${appName}\n${e.window_title || ''}\n${timeRange}\n${durMin}m ${durSec}s`,
    }
  })
})

const timelineStartLabel = computed(() => {
  if (timelineEvents.value.length === 0) return ''
  return formatTimeHM(timelineEvents.value[0].started_at)
})

const timelineEndLabel = computed(() => {
  if (timelineEvents.value.length === 0) return ''
  const last = timelineEvents.value[timelineEvents.value.length - 1]
  return last.ended_at ? formatTimeHM(last.ended_at) : 'now'
})

const timelineApps = computed(() => {
  const seen = new Map<string, string>()
  for (const e of timelineEvents.value) {
    const name = e.exe_name || 'Unknown'
    if (!seen.has(name)) {
      seen.set(name, hashColor(name))
    }
  }
  return Array.from(seen.entries()).map(([name, color]) => ({ name, color }))
})

function formatTimeHM(iso: string): string {
  const d = new Date(iso)
  return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
}

async function toggleTimelinePanel() {
  timelineExpanded.value = !timelineExpanded.value
  if (timelineExpanded.value) {
    await fetchTimelineEvents()
  }
}

async function fetchTimelineEvents() {
  if (!selectedProject.value) {
    timelineEvents.value = []
    return
  }
  const today = new Date().toISOString().split('T')[0]
  try {
    timelineEvents.value = await invoke<TimelineEvent[]>('get_timeline_events', {
      projectId: selectedProject.value,
      date: today,
    })
  } catch (e) {
    console.error('Failed to fetch timeline events:', e)
    timelineEvents.value = []
  }
}

async function clearTodayTimeline() {
  if (!selectedProject.value) return
  const today = new Date().toISOString().split('T')[0]
  try {
    await invoke('delete_timeline_events', {
      projectId: selectedProject.value,
      date: today,
    })
    timelineEvents.value = []
    toastStore.success('Timeline cleared')
  } catch (e) {
    console.error('Failed to clear timeline:', e)
    toastStore.error('Failed to clear timeline')
  }
}

// Split timer into parts for colon animation
const timerParts = computed(() => {
  const time = timerStore.formattedTime
  const parts = time.split(':')
  return {
    hours: parts[0] || '00',
    minutes: parts[1] || '00',
    seconds: parts[2] || '00'
  }
})

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

// Recent entries (last 5)
const recentEntries = computed(() => {
  return entriesStore.entries.slice(0, 5)
})

// Button appearance
const buttonLabel = computed(() => {
  if (timerStore.isStopped) return 'Start'
  if (timerStore.isPaused) return 'Stop'
  return 'Stop'
})

const buttonClass = computed(() => {
  if (timerStore.isStopped) return 'bg-accent text-bg-base hover:bg-accent-hover'
  return 'bg-status-error text-white hover:bg-status-error/80'
})

// Timer start/stop pulse animation
watch(() => timerStore.isRunning, (isRunning, wasRunning) => {
  if (isRunning && !wasRunning) {
    timerPulseClass.value = 'animate-timer-pulse'
    setTimeout(() => { timerPulseClass.value = '' }, 300)
  }
})

watch(() => timerStore.isStopped, (isStopped, wasStopped) => {
  if (isStopped && !wasStopped) {
    timerPulseClass.value = 'animate-timer-glow'
    setTimeout(() => { timerPulseClass.value = '' }, 600)
  }
})

// Watch project selection and fetch tasks
watch(selectedProject, async (newProjectId) => {
  timerStore.setProject(newProjectId)
  selectedTask.value = null
  projectTasks.value = []
  projectBudgetStatus.value = null

  if (newProjectId) {
    projectTasks.value = await projectsStore.fetchTasks(newProjectId)
    const project = projectsStore.projects.find(p => p.id === newProjectId)
    if (project?.budget_hours) {
      try {
        const today = new Date().toISOString().split('T')[0]
        const status = await invoke<{ hours_used: number }>('get_project_budget_status', { projectId: newProjectId, today })
        projectBudgetStatus.value = {
          hoursUsed: status.hours_used,
          budgetHours: project.budget_hours,
          pct: (status.hours_used / project.budget_hours) * 100,
        }
      } catch {
        projectBudgetStatus.value = null
      }
    }
  }
})

// Watch task selection
watch(selectedTask, (newTaskId) => {
  timerStore.setTask(newTaskId)
})

// Watch description
watch(description, (newDesc) => {
  timerStore.setDescription(newDesc)
})

// Bring window to front when prompts appear
async function bringToFront() {
  try {
    const { getCurrentWindow } = await import('@tauri-apps/api/window')
    const win = getCurrentWindow()
    await win.show()
    await win.setFocus()
  } catch (e) {
    // Ignore if not in Tauri context
  }
}

watch(() => timerStore.showIdlePrompt, (show) => {
  if (show) bringToFront()
})

watch(() => timerStore.showAppPrompt, (show) => {
  if (show) bringToFront()
})

// Send OS notification when entering PAUSED_APP in "notify" mode
watch(() => timerStore.timerState, async (newState, oldState) => {
  if (newState === 'PAUSED_APP' && oldState === 'RUNNING') {
    const mode = settingsStore.settings.app_tracking_mode || 'auto'
    if (mode === 'notify') {
      try {
        const { sendNotification } = await import('@tauri-apps/plugin-notification')
        sendNotification({
          title: 'ZeroClock',
          body: 'Tracked app is no longer visible. Timer paused.',
        })
      } catch (e) {
        // Ignore
      }
    }
  }
})

// Open mini timer pop-out
async function openMiniTimer() {
  await invoke('open_mini_timer')
}

// Toggle timer
async function toggleTimer() {
  if (timerStore.isStopped) {
    if (!selectedProject.value) {
      toastStore.info('Please select a project before starting the timer')
      return
    }
    timerStore.start()
  } else {
    timerStore.stop()
    await entriesStore.fetchEntries()

    // Save tags for the new entry if any were selected
    if (selectedTags.value.length > 0) {
      const entries = entriesStore.entries
      if (entries.length > 0 && entries[0].id) {
        await tagsStore.setEntryTags(entries[0].id, selectedTags.value)
      }
    }
    selectedTags.value = []

    // Check for overlapping entries (non-blocking warning)
    const latestEntry = entriesStore.entries[0]
    if (latestEntry?.start_time && latestEntry?.end_time) {
      try {
        const overlaps = await invoke<Array<{ project_name: string }>>('check_entry_overlap', {
          startTime: latestEntry.start_time,
          endTime: latestEntry.end_time,
          excludeId: latestEntry.id,
        })
        if (overlaps.length > 0) {
          toastStore.info(`This entry overlaps with ${overlaps.length} other ${overlaps.length === 1 ? 'entry' : 'entries'}`)
        }
      } catch { /* non-critical */ }
    }
  }
}

// Idle prompt handlers
function onIdleContinueKeep() {
  timerStore.handleIdleContinueKeep()
}

function onIdleContinueSubtract() {
  timerStore.handleIdleContinueSubtract()
}

async function onIdleStop() {
  await timerStore.handleIdleStop()
  entriesStore.fetchEntries()
}

// App prompt handlers
function onAppContinue() {
  timerStore.handleAppContinue()
}

async function onAppStop() {
  await timerStore.handleAppStop()
  entriesStore.fetchEntries()
}

// Repeat an entry (fill in project/task/description)
function repeatEntry(entry: { project_id: number; task_id?: number; description?: string }) {
  selectedProject.value = entry.project_id
  selectedTask.value = entry.task_id || null
  description.value = entry.description || ''
}

// Apply a favorite to the inputs
function applyFavorite(fav: Favorite) {
  selectedProject.value = fav.project_id
  selectedTask.value = fav.task_id || null
  description.value = fav.description || ''
}

// Quick-start a favorite (starts timer immediately)
async function quickStartFavorite(fav: Favorite) {
  if (!timerStore.isStopped) {
    timerStore.stop()
    await entriesStore.fetchEntries()
  }
  selectedProject.value = fav.project_id
  selectedTask.value = fav.task_id || null
  description.value = fav.description || ''
  timerStore.setProject(fav.project_id)
  timerStore.setTask(fav.task_id || null)
  timerStore.setDescription(fav.description || '')
  timerStore.start()
  toastStore.success('Timer started for ' + getProjectName(fav.project_id))
}

// Quick-switch state
const showSwitchPicker = ref(false)

async function switchToProject(projectId: number | null) {
  if (!projectId) return
  showSwitchPicker.value = false
  timerStore.stop()
  await entriesStore.fetchEntries()
  selectedProject.value = projectId
  selectedTask.value = null
  description.value = ''
  timerStore.setProject(projectId)
  timerStore.setTask(null)
  timerStore.setDescription('')
  timerStore.start()
  toastStore.success('Switched to ' + getProjectName(projectId))
}

// Drag-reorder favorites
const dragFavIndex = ref<number | null>(null)
const dropTargetIndex = ref<number | null>(null)

function onFavDragStart(index: number) {
  dragFavIndex.value = index
  window.addEventListener('pointerup', onFavDragEnd, { once: true })
}

function onFavDragOver(index: number) {
  if (dragFavIndex.value !== null) {
    dropTargetIndex.value = index
  }
}

function onFavDragCancel() {
  if (dragFavIndex.value !== null) {
    dropTargetIndex.value = null
  }
}

function onFavDragEnd() {
  const from = dragFavIndex.value
  const to = dropTargetIndex.value
  if (from !== null && to !== null && from !== to) {
    const reordered = [...favoritesStore.favorites]
    const [moved] = reordered.splice(from, 1)
    // Adjust insertion index: if dropping after the dragged item's original position,
    // the index shifts down by 1 since we already removed the item
    const insertAt = to > from ? to - 1 : to
    reordered.splice(insertAt, 0, moved)
    favoritesStore.reorderFavorites(reordered.map(f => f.id!))
  }
  dragFavIndex.value = null
  dropTargetIndex.value = null
}

function moveFavorite(index: number, direction: -1 | 1) {
  const newIndex = index + direction
  if (newIndex < 0 || newIndex >= favoritesStore.favorites.length) return
  const reordered = [...favoritesStore.favorites]
  const [moved] = reordered.splice(index, 1)
  reordered.splice(newIndex, 0, moved)
  favoritesStore.reorderFavorites(reordered.map(f => f.id!))
}

// Delete a favorite
async function removeFavorite(id: number) {
  await favoritesStore.deleteFavorite(id)
}

// Save current inputs as a favorite
async function saveAsFavorite() {
  if (!selectedProject.value) return
  await favoritesStore.createFavorite({
    project_id: selectedProject.value,
    task_id: selectedTask.value || undefined,
    description: description.value || undefined,
    sort_order: favoritesStore.favorites.length,
  })
}

// 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'
}

// 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`
}

// Load data on mount
onMounted(async () => {
  await Promise.all([
    projectsStore.fetchProjects(),
    entriesStore.fetchEntries(),
    settingsStore.fetchSettings(),
    favoritesStore.fetchFavorites(),
    tagsStore.fetchTags(),
    loadRecentDescriptions()
  ])

  // Restore timer state
  selectedProject.value = timerStore.selectedProjectId
  selectedTask.value = timerStore.selectedTaskId
  description.value = timerStore.description
})
</script>
