<script setup lang="ts">
import { ref, watch, nextTick, onUnmounted, computed } from 'vue'
import { useFocusTrap } from '../utils/focusTrap'
import { useAnnouncer } from '../composables/useAnnouncer'
import AppSelect from './AppSelect.vue'
import AppDatePicker from './AppDatePicker.vue'
import AppTimePicker from './AppTimePicker.vue'
import { useProjectsStore, type Task } from '../stores/projects'
import { useEntriesStore } from '../stores/entries'
import { useSettingsStore } from '../stores/settings'
import { useToastStore } from '../stores/toast'
import { X } from 'lucide-vue-next'

const props = defineProps<{
  show: boolean
}>()

const emit = defineEmits<{
  close: []
  saved: []
}>()

const projectsStore = useProjectsStore()
const entriesStore = useEntriesStore()
const settingsStore = useSettingsStore()
const toastStore = useToastStore()
const { activate: activateTrap, deactivate: deactivateTrap } = useFocusTrap()
const { announce } = useAnnouncer()
const dialogRef = ref<HTMLElement | null>(null)

const selectedProjectId = ref<number | null>(null)
const selectedTaskId = ref<number | null>(null)
const description = ref('')
const entryDate = ref(new Date().toISOString().split('T')[0])
const durationHour = ref(1)
const durationMinute = ref(0)
const billable = ref(1)
const tasks = ref<Task[]>([])
const saving = ref(false)

const availableProjects = computed(() => projectsStore.activeProjects)

const canSave = computed(() => !!selectedProjectId.value && (durationHour.value > 0 || durationMinute.value > 0) && !saving.value)

watch(selectedProjectId, async (projectId) => {
  selectedTaskId.value = null
  if (projectId) {
    tasks.value = await projectsStore.fetchTasks(projectId)
  } else {
    tasks.value = []
  }
})

watch(() => props.show, async (val) => {
  if (val) {
    // Ensure projects are loaded
    if (projectsStore.projects.length === 0) {
      await projectsStore.fetchProjects()
    }

    // Reset form
    const lastProjectId = parseInt(settingsStore.settings.last_project_id) || 0
    selectedProjectId.value = lastProjectId || null
    selectedTaskId.value = null
    description.value = ''
    entryDate.value = new Date().toISOString().split('T')[0]
    durationHour.value = 1
    durationMinute.value = 0
    billable.value = 1
    saving.value = false

    await nextTick()
    if (dialogRef.value) {
      activateTrap(dialogRef.value, { onDeactivate: () => emit('close') })
    }
    announce('Quick entry dialog opened')
  } else {
    deactivateTrap()
  }
})

onUnmounted(() => deactivateTrap())

async function handleSave() {
  const duration = durationHour.value * 3600 + durationMinute.value * 60
  if (!selectedProjectId.value || duration <= 0) return

  saving.value = true

  const startDate = new Date(entryDate.value + 'T09:00:00')
  const endDate = new Date(startDate.getTime() + duration * 1000)

  try {
    await entriesStore.createEntry({
      project_id: selectedProjectId.value,
      task_id: selectedTaskId.value || undefined,
      description: description.value || undefined,
      start_time: startDate.toISOString(),
      end_time: endDate.toISOString(),
      duration,
      billable: billable.value,
    })

    // Save last-used project
    await settingsStore.updateSetting('last_project_id', String(selectedProjectId.value))

    toastStore.success('Entry created')
    announce('Time entry created successfully')
    emit('saved')
    emit('close')
  } catch {
    toastStore.error('Failed to create entry')
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <Teleport to="#app">
    <Transition name="modal">
      <div
        v-if="show"
        class="fixed inset-0 bg-black/70 backdrop-blur-[4px] flex items-center justify-center p-4 z-50"
        @click.self="$emit('close')"
      >
        <div
          ref="dialogRef"
          role="dialog"
          aria-modal="true"
          aria-labelledby="quick-entry-title"
          class="bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] w-full max-w-md p-6"
        >
          <div class="flex items-center justify-between mb-4">
            <h2 id="quick-entry-title" class="text-[1.125rem] font-semibold font-[family-name:var(--font-heading)] text-text-primary">
              Quick Entry
            </h2>
            <button
              @click="$emit('close')"
              class="p-1 text-text-tertiary hover:text-text-primary transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
              aria-label="Close"
              v-tooltip="'Close'"
            >
              <X class="w-4 h-4" aria-hidden="true" />
            </button>
          </div>

          <form @submit.prevent="handleSave" class="space-y-3">
            <div>
              <label class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Project *</label>
              <AppSelect
                v-model="selectedProjectId"
                :options="availableProjects"
                label-key="name"
                value-key="id"
                placeholder="Select project"
                :searchable="true"
              />
            </div>

            <div v-if="tasks.length > 0">
              <label class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Task</label>
              <AppSelect
                v-model="selectedTaskId"
                :options="tasks"
                label-key="name"
                value-key="id"
                placeholder="No task"
                :placeholder-value="null"
              />
            </div>

            <div>
              <label for="quick-entry-desc" class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Description</label>
              <input
                id="quick-entry-desc"
                v-model="description"
                type="text"
                class="w-full px-3 py-2 bg-bg-inset border border-border-subtle rounded-lg text-[0.8125rem] text-text-primary focus:outline-none focus:border-border-visible"
                placeholder="What did you work on?"
              />
            </div>

            <div class="grid grid-cols-2 gap-3">
              <div>
                <label class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Date</label>
                <AppDatePicker v-model="entryDate" />
              </div>
              <div>
                <label class="block text-[0.6875rem] text-text-tertiary uppercase tracking-[0.08em] mb-1.5">Duration *</label>
                <AppTimePicker
                  v-model:hour="durationHour"
                  v-model:minute="durationMinute"
                  placeholder="Duration"
                />
              </div>
            </div>

            <div class="flex items-center gap-2">
              <button
                type="button"
                @click="billable = billable ? 0 : 1"
                role="switch"
                :aria-checked="!!billable"
                aria-label="Billable"
                class="relative inline-flex h-5 w-9 items-center rounded-full transition-colors duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
                :class="billable ? 'bg-status-running' : 'bg-bg-elevated'"
              >
                <span
                  class="inline-block h-3.5 w-3.5 transform rounded-full bg-text-primary transition-transform duration-150"
                  :class="billable ? 'translate-x-[18px]' : 'translate-x-[3px]'"
                  aria-hidden="true"
                />
              </button>
              <span class="text-[0.75rem] text-text-secondary">Billable</span>
            </div>

            <div class="flex justify-end gap-2 pt-2">
              <button
                type="button"
                @click="$emit('close')"
                class="px-4 py-2 text-[0.8125rem] text-text-secondary border border-border-subtle rounded-lg hover:bg-bg-elevated transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
              >
                Cancel
              </button>
              <button
                type="submit"
                :disabled="!canSave"
                class="px-4 py-2 text-[0.8125rem] bg-accent text-bg-base rounded-lg hover:bg-accent-hover transition-colors disabled:opacity-40 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
              >
                Save
              </button>
            </div>
          </form>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>
