<script setup lang="ts">
import { computed, ref, toRef, watch } from 'vue'
import { VForm } from 'vuetify/components/VForm'
import { useTimetableMutations } from '@/composables/api/useTimetableMutations'
import { createPerformancePayloadSchema } from '@/schemas/timetable'
import type { ArtistEngagement, Stage } from '@/types/timetable'
import { requiredValidator } from '@core/utils/validators'

const props = defineProps<{
  modelValue: boolean
  orgId: string
  eventId: string
  dayId: string | null
  stages: Stage[]
  /** Engagements available to schedule (filtered to this event). */
  engagements: ArtistEngagement[]
  /** Pre-fill from a drag-out-on-empty-cell (optional). */
  prefill?: { stageId: string; startAt: string; endAt: string; lane: number } | null
}>()

const emit = defineEmits<{
  'update:modelValue': [open: boolean]
  'created': []
}>()

const orgIdRef = toRef(props, 'orgId')
const eventIdRef = toRef(props, 'eventId')
const dayIdRef = toRef(props, 'dayId')

const refForm = ref<VForm>()
const errors = ref<Record<string, string>>({})

const form = ref({
  engagement_id: '',
  stage_id: null as string | null,
  start_at: '',
  end_at: '',
  lane: 0,
  notes: '',
})

watch(() => props.modelValue, open => {
  if (open) {
    form.value = {
      engagement_id: '',
      stage_id: props.prefill?.stageId ?? null,
      start_at: props.prefill?.startAt ?? '',
      end_at: props.prefill?.endAt ?? '',
      lane: props.prefill?.lane ?? 0,
      notes: '',
    }
    errors.value = {}
  }
})

const mutations = useTimetableMutations({ orgId: orgIdRef, eventId: eventIdRef, dayId: dayIdRef })
const isPending = computed(() => mutations.create.isPending.value)

const engagementOptions = computed(() =>
  props.engagements.map(e => ({
    title: e.artist?.name ?? '—',
    subtitle: e.booking_status?.label ?? '',
    value: e.id,
  })),
)

async function submit(): Promise<void> {
  errors.value = {}

  const eventIdValue = props.dayId ?? props.eventId

  const payload = {
    engagement_id: form.value.engagement_id,
    event_id: eventIdValue,
    stage_id: form.value.stage_id,
    start_at: form.value.start_at,
    end_at: form.value.end_at,
    lane: form.value.lane,
    notes: form.value.notes || null,
  }

  const parsed = createPerformancePayloadSchema.safeParse(payload)
  if (!parsed.success) {
    for (const issue of parsed.error.issues)
      errors.value[String(issue.path[0] ?? '_')] = issue.message

    return
  }

  try {
    await mutations.create.mutateAsync(parsed.data)
    emit('created')
    emit('update:modelValue', false)
  }
  catch (err) {
    errors.value._ = (err as Error).message ?? 'Onbekende fout'
  }
}

// Test seam (Session 4 follow-up): expose form + errors + submit so jsdom
// component tests can drive validation deterministically without piping
// through Flatpickr / VAutocomplete plumbing.
defineExpose({ form, errors, submit })
</script>

<template>
  <VDialog
    :model-value="modelValue"
    max-width="520"
    persistent
    @update:model-value="emit('update:modelValue', $event)"
  >
    <VCard>
      <VCardTitle class="d-flex justify-space-between align-center">
        Nieuw optreden plannen
        <VBtn
          icon="tabler-x"
          variant="text"
          size="small"
          @click="emit('update:modelValue', false)"
        />
      </VCardTitle>
      <VForm
        ref="refForm"
        @submit.prevent="submit"
      >
        <VCardText class="d-flex flex-column gap-4">
          <VAlert
            v-if="errors._"
            type="error"
            density="compact"
            variant="tonal"
          >
            {{ errors._ }}
          </VAlert>
          <AppAutocomplete
            v-model="form.engagement_id"
            label="Artiest / engagement"
            :items="engagementOptions"
            item-title="title"
            item-value="value"
            :rules="[requiredValidator]"
            :error-messages="errors.engagement_id"
            autofocus
          />
          <AppSelect
            v-model="form.stage_id"
            label="Stage"
            :items="stages.map(s => ({ title: s.name, value: s.id }))"
            clearable
            :error-messages="errors.stage_id"
          />
          <div class="d-flex gap-3">
            <AppDateTimePicker
              v-model="form.start_at"
              label="Start"
              :rules="[requiredValidator]"
              :error-messages="errors.start_at"
              :config="{ enableTime: true, dateFormat: 'Y-m-d H:i', time_24hr: true }"
            />
            <AppDateTimePicker
              v-model="form.end_at"
              label="Einde"
              :rules="[requiredValidator]"
              :error-messages="errors.end_at"
              :config="{ enableTime: true, dateFormat: 'Y-m-d H:i', time_24hr: true }"
            />
          </div>
          <AppTextField
            v-model.number="form.lane"
            label="Lane"
            type="number"
            min="0"
            max="9"
            :error-messages="errors.lane"
          />
          <AppTextarea
            v-model="form.notes"
            label="Notities"
            rows="2"
            :error-messages="errors.notes"
          />
        </VCardText>
        <VCardActions class="px-4 pb-4">
          <VSpacer />
          <VBtn
            variant="tonal"
            @click="emit('update:modelValue', false)"
          >
            Annuleer
          </VBtn>
          <VBtn
            type="submit"
            color="primary"
            :loading="isPending"
          >
            Plannen
          </VBtn>
        </VCardActions>
      </VForm>
    </VCard>
  </VDialog>
</template>
