<script setup lang="ts">
import { VForm } from 'vuetify/components/VForm'
import { useCreateShift, useUpdateShift } from '@/composables/api/useShifts'
import { useTimeSlotList } from '@/composables/api/useTimeSlots'
import { requiredValidator } from '@core/utils/validators'
import type { Shift, ShiftStatus } from '@/types/section'

const props = withDefaults(defineProps<{
  eventId: string
  sectionId: string
  shift?: Shift | null
  isSubEvent?: boolean
}>(), {
  isSubEvent: false,
})

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

const modelValue = defineModel<boolean>({ required: true })

const eventIdRef = computed(() => props.eventId)
const sectionIdRef = computed(() => props.sectionId)

const isEditing = computed(() => !!props.shift)
const isSubEventRef = computed(() => props.isSubEvent)

const { data: timeSlots } = useTimeSlotList(eventIdRef, { includeParent: isSubEventRef })
const { mutate: createShift, isPending: isCreating } = useCreateShift(eventIdRef, sectionIdRef)
const { mutate: updateShift, isPending: isUpdating } = useUpdateShift(eventIdRef, sectionIdRef)

const isPending = computed(() => isCreating.value || isUpdating.value)

const form = ref({
  time_slot_id: '',
  title: '',
  report_time: '',
  actual_start_time: '',
  actual_end_time: '',
  slots_total: 1,
  slots_open_for_claiming: 0,
  is_lead_role: false,
  allow_overlap: false,
  instructions: '',
  status: 'draft' as ShiftStatus,
})

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

// Populate form when editing
watch(
  () => props.shift,
  (shift) => {
    if (shift) {
      form.value = {
        time_slot_id: shift.time_slot_id,
        title: shift.title ?? '',
        report_time: shift.report_time ?? '',
        actual_start_time: shift.actual_start_time ?? '',
        actual_end_time: shift.actual_end_time ?? '',
        slots_total: shift.slots_total,
        slots_open_for_claiming: shift.slots_open_for_claiming,
        is_lead_role: shift.is_lead_role,
        allow_overlap: shift.allow_overlap,
        instructions: shift.instructions ?? '',
        status: shift.status,
      }
    }
  },
  { immediate: true },
)

const timeSlotItems = computed(() => {
  if (!timeSlots.value?.length) return []

  const hasFestival = timeSlots.value.some(ts => ts.source === 'festival')
  if (!hasFestival) {
    return timeSlots.value.map(ts => ({
      title: `${ts.name} — ${ts.date} ${ts.start_time}–${ts.end_time}`,
      value: ts.id,
    }))
  }

  const subEventSlots = timeSlots.value.filter(ts => ts.source !== 'festival')
  const festivalSlots = timeSlots.value.filter(ts => ts.source === 'festival')
  const items: Array<{ title: string; value?: string; type?: string }> = []

  if (subEventSlots.length) {
    items.push({ title: subEventSlots[0]?.event_name ?? 'Programma', type: 'subheader' })
    items.push(...subEventSlots.map(ts => ({
      title: `${ts.name} — ${ts.date} ${ts.start_time}–${ts.end_time}`,
      value: ts.id,
    })))
  }

  if (festivalSlots.length) {
    items.push({ title: festivalSlots[0]?.event_name ?? 'Festival', type: 'subheader' })
    items.push(...festivalSlots.map(ts => ({
      title: `${ts.name} — ${ts.date} ${ts.start_time}–${ts.end_time}`,
      value: ts.id,
    })))
  }

  return items
})

const statusOptions = [
  { title: 'Concept', value: 'draft' },
  { title: 'Open', value: 'open' },
]

function resetForm() {
  form.value = {
    time_slot_id: '',
    title: '',
    report_time: '',
    actual_start_time: '',
    actual_end_time: '',
    slots_total: 1,
    slots_open_for_claiming: 0,
    is_lead_role: false,
    allow_overlap: false,
    instructions: '',
    status: 'draft',
  }
  errors.value = {}
  refVForm.value?.resetValidation()
}

function buildPayload() {
  return {
    time_slot_id: form.value.time_slot_id,
    slots_total: form.value.slots_total,
    slots_open_for_claiming: form.value.slots_open_for_claiming,
    is_lead_role: form.value.is_lead_role,
    allow_overlap: form.value.allow_overlap,
    status: form.value.status,
    ...(form.value.title ? { title: form.value.title } : {}),
    ...(form.value.report_time ? { report_time: form.value.report_time } : {}),
    ...(form.value.actual_start_time ? { actual_start_time: form.value.actual_start_time } : {}),
    ...(form.value.actual_end_time ? { actual_end_time: form.value.actual_end_time } : {}),
    ...(form.value.instructions ? { instructions: form.value.instructions } : {}),
  }
}

function onSubmit() {
  refVForm.value?.validate().then(({ valid }) => {
    if (!valid) return

    errors.value = {}

    const callbacks = {
      onSuccess: () => {
        modelValue.value = false
      },
      onError: (err: any) => {
        const data = err.response?.data
        if (data?.errors) {
          errors.value = Object.fromEntries(
            Object.entries(data.errors).map(([k, v]) => [k, (v as string[])[0]]),
          )
        }
      },
    }

    if (isEditing.value && props.shift) {
      updateShift({ id: props.shift.id, ...buildPayload() }, callbacks)
    }
    else {
      createShift(buildPayload(), callbacks)
    }
  })
}
</script>

<template>
  <VDialog
    v-model="modelValue"
    max-width="600"
    @after-leave="!isEditing && resetForm()"
  >
    <VCard :title="isEditing ? 'Shift bewerken' : 'Shift toevoegen'">
      <VForm
        ref="refVForm"
        @submit.prevent="onSubmit"
      >
        <VCardText>
          <VRow>
            <VCol cols="12">
              <AppSelect
                v-if="timeSlotItems.length"
                v-model="form.time_slot_id"
                label="Time Slot"
                :items="timeSlotItems"
                :rules="[requiredValidator]"
                :error-messages="errors.time_slot_id"
              />
              <VAlert
                v-else
                type="info"
                variant="tonal"
              >
                <div class="d-flex align-center justify-space-between flex-wrap gap-2">
                  <span>Maak eerst een time slot aan</span>
                  <VBtn
                    size="small"
                    variant="text"
                    color="primary"
                    prepend-icon="tabler-clock"
                    @click="emit('openTimeSlots'); modelValue = false"
                  >
                    Time Slots beheren
                  </VBtn>
                </div>
              </VAlert>
            </VCol>
            <VCol cols="12">
              <AppTextField
                v-model="form.title"
                label="Titel / Rol"
                placeholder="Tapper, Barhoofd, Stage Manager..."
                :error-messages="errors.title"
                autocomplete="one-time-code"
              />
            </VCol>
            <VCol
              cols="12"
              sm="4"
            >
              <AppTextField
                v-model="form.report_time"
                label="Aanwezig om (rapport tijd)"
                type="time"
                :error-messages="errors.report_time"
              />
            </VCol>
            <VCol
              cols="12"
              sm="4"
            >
              <AppTextField
                v-model="form.actual_start_time"
                label="Afwijkende starttijd"
                type="time"
                hint="Leeg = time slot tijd"
                persistent-hint
                :error-messages="errors.actual_start_time"
              />
            </VCol>
            <VCol
              cols="12"
              sm="4"
            >
              <AppTextField
                v-model="form.actual_end_time"
                label="Afwijkende eindtijd"
                type="time"
                :error-messages="errors.actual_end_time"
              />
            </VCol>
            <VCol
              cols="12"
              sm="6"
            >
              <AppTextField
                v-model.number="form.slots_total"
                label="Totaal slots"
                type="number"
                min="1"
                :rules="[requiredValidator]"
                :error-messages="errors.slots_total"
              />
            </VCol>
            <VCol
              cols="12"
              sm="6"
            >
              <AppTextField
                v-model.number="form.slots_open_for_claiming"
                label="Open voor claimen"
                type="number"
                min="0"
                :max="form.slots_total"
                :rules="[requiredValidator]"
                :error-messages="errors.slots_open_for_claiming"
              />
            </VCol>
            <VCol cols="12">
              <VSwitch
                v-model="form.is_lead_role"
                label="Dit is een leidinggevende rol"
              />
            </VCol>
            <VCol cols="12">
              <VSwitch
                v-model="form.allow_overlap"
                label="Overlap toegestaan"
                hint="Persoon mag meerdere shifts in hetzelfde tijdvak hebben"
                persistent-hint
              />
            </VCol>
            <VCol cols="12">
              <AppTextarea
                v-model="form.instructions"
                label="Instructies"
                rows="3"
                :error-messages="errors.instructions"
                autocomplete="one-time-code"
              />
            </VCol>
            <VCol cols="12">
              <AppSelect
                v-model="form.status"
                label="Status"
                :items="statusOptions"
                :error-messages="errors.status"
              />
            </VCol>
          </VRow>
        </VCardText>
        <VCardActions>
          <VSpacer />
          <VBtn
            variant="text"
            @click="modelValue = false"
          >
            Annuleren
          </VBtn>
          <VBtn
            type="submit"
            color="primary"
            :loading="isPending"
          >
            {{ isEditing ? 'Opslaan' : 'Toevoegen' }}
          </VBtn>
        </VCardActions>
      </VForm>
    </VCard>
  </VDialog>
</template>
