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

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

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

const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()

const orgIdRef = computed(() => authStore.currentOrganisation?.id ?? '')
const eventIdRef = computed(() => props.eventId)
const sectionIdRef = computed(() => props.sectionId)

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

// Get full event detail for hierarchy info
const { data: eventDetail } = useEventDetail(orgIdRef, eventIdRef)
const sectionRef = computed(() => props.section ?? null)

// Determine dropdown scenario
const { scenario, showInfoTooltip, hasGroups, tooltipText, fetchParams, sortedItems } = useTimeSlotDropdown(
  eventDetail,
  sectionRef,
)

// Fetch time slots based on scenario
const includeParentRef = computed(() => fetchParams.value.includeParent)
const includeChildrenRef = computed(() => fetchParams.value.includeChildren)

const { data: timeSlots, isLoading: timeSlotsLoading } = useTimeSlotList(orgIdRef, eventIdRef, {
  includeParent: includeParentRef,
  includeChildren: includeChildrenRef,
})

const { mutate: createShift, isPending: isCreating } = useCreateShift(orgIdRef, eventIdRef, sectionIdRef)
const { mutate: updateShift, isPending: isUpdating } = useUpdateShift(orgIdRef, 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>()

/** Time-slot hierarchy uitleg (ingeklapt = minder visuele ruis). */
const timeSlotHelpOpen = ref(false)

watch(modelValue, (open) => {
  if (open)
    timeSlotHelpOpen.value = false
})

function toggleTimeSlotHelp() {
  timeSlotHelpOpen.value = !timeSlotHelpOpen.value
}

// 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 },
)

// Build sorted dropdown items (no fake header items — groups are detected by boundary)
const dropdownItems = computed(() => {
  // While loading, show the current shift's time slot so the dropdown doesn't flash a raw ULID
  if (!timeSlots.value?.length) {
    if (props.shift?.time_slot) {
      const ts = props.shift.time_slot
      return [{
        id: ts.id,
        name: ts.name,
        timeRange: `${ts.start_time} – ${ts.end_time}`,
        displayLabel: ts.name,
        _isDimmed: false,
        groupName: '',
      }]
    }
    return []
  }

  return sortedItems(timeSlots.value)
})

const hasTimeSlots = computed(() => dropdownItems.value.length > 0)

// Detect group boundaries: true when the current item starts a new group
function isNewGroup(index: number): boolean {
  if (index === 0) return true
  return dropdownItems.value[index]?.groupName !== dropdownItems.value[index - 1]?.groupName
}

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="640"
    @after-leave="!isEditing && resetForm()"
  >
    <VCard
      class="d-flex flex-column overflow-hidden"
      max-height="min(90vh, 880px)"
      rounded="lg"
    >
      <VCardItem class="flex-shrink-0 pb-3 pt-5 px-6">
        <VCardTitle class="text-h6 ps-0">
          {{ isEditing ? 'Shift bewerken' : 'Shift toevoegen' }}
        </VCardTitle>
        <VCardSubtitle
          v-if="section"
          class="text-body-2 mt-2 ps-0 d-flex align-center flex-wrap gap-2"
        >
          <span class="text-high-emphasis">{{ section.name }}</span>
          <VChip
            v-if="section.type === 'cross_event'"
            size="small"
            color="info"
            variant="tonal"
          >
            festival-breed
          </VChip>
          <span
            v-else-if="isSubEvent && eventDetail?.name"
            class="text-medium-emphasis"
          >· {{ eventDetail.name }}</span>
        </VCardSubtitle>
      </VCardItem>

      <VDivider class="flex-shrink-0" />

      <VForm
        ref="refVForm"
        class="d-flex flex-column flex-grow-1"
        style="min-height: 0"
        @submit.prevent="onSubmit"
      >
        <VCardText
          class="flex-grow-1 overflow-y-auto px-6 py-5"
          style="min-height: 0"
        >
          <VAlert
            v-if="showInfoTooltip && tooltipText"
            variant="tonal"
            type="info"
            border="start"
            border-color="info"
            density="comfortable"
            :icon="false"
            class="mb-6 pa-0 overflow-hidden"
          >
            <div
              role="button"
              tabindex="0"
              class="cursor-pointer pa-4 text-start"
              :aria-expanded="timeSlotHelpOpen"
              aria-controls="shift-time-slot-help"
              @click="toggleTimeSlotHelp"
              @keydown.enter.prevent="toggleTimeSlotHelp"
              @keydown.space.prevent="toggleTimeSlotHelp"
            >
              <div class="d-flex align-start gap-3">
                <VIcon
                  icon="tabler-info-circle"
                  color="info"
                  size="22"
                  class="flex-shrink-0 align-self-start"
                />
                <div class="flex-grow-1 min-width-0">
                  <div class="d-flex align-center flex-nowrap gap-2">
                    <span class="text-body-1 font-weight-medium text-high-emphasis flex-grow-1 min-width-0">
                      Tijdsloten in dit evenement
                    </span>
                    <VIcon
                      :icon="timeSlotHelpOpen ? 'tabler-chevron-up' : 'tabler-chevron-down'"
                      size="22"
                      class="text-medium-emphasis flex-shrink-0"
                    />
                  </div>
                  <VExpandTransition>
                    <div
                      v-show="timeSlotHelpOpen"
                      id="shift-time-slot-help"
                      class="text-body-2 mt-3 text-medium-emphasis"
                    >
                      <p class="mb-2 text-high-emphasis">
                        {{ tooltipText.main }}
                      </p>
                      <p class="text-caption mb-0">
                        <span class="font-weight-semibold text-high-emphasis">Tip:</span>
                        {{ tooltipText.tip }}
                      </p>
                    </div>
                  </VExpandTransition>
                </div>
              </div>
            </div>
          </VAlert>

          <p class="text-caption font-weight-bold text-uppercase text-medium-emphasis tracking-normal mb-3">
            Tijd & rol
          </p>
          <VRow>
            <VCol cols="12">
              <VAutocomplete
                v-if="timeSlotsLoading || hasTimeSlots"
                v-model="form.time_slot_id"
                :items="dropdownItems"
                item-title="displayLabel"
                item-value="id"
                label="Tijdslot"
                :loading="timeSlotsLoading"
                :rules="[requiredValidator]"
                :error-messages="errors.time_slot_id"
                hide-details="auto"
              >
                <template #item="{ props: itemProps, item, index }">
                  <!-- Group header: rendered when event_name changes -->
                  <VListSubheader
                    v-if="hasGroups && isNewGroup(index)"
                    :title="item.raw.groupName"
                  />

                  <VListItem
                    v-bind="itemProps"
                    :style="item.raw._isDimmed ? 'opacity: 0.55' : ''"
                  >
                    <template #title>
                      {{ item.raw.name }}
                    </template>
                    <template #append>
                      <span class="text-caption text-medium-emphasis">
                        {{ item.raw.timeRange }}
                      </span>
                    </template>
                  </VListItem>
                </template>

                <template #selection="{ item }">
                  {{ item.raw.name }} · {{ item.raw.timeRange }}
                </template>
              </VAutocomplete>
              <VAlert
                v-else
                type="info"
                variant="tonal"
                border="start"
                border-color="info"
                density="comfortable"
              >
                <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="modelValue = false; router.push({ name: 'events-id-time-slots', params: { id: (route.params as { id: string }).id } })"
                  >
                    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>
          </VRow>

          <VDivider class="my-4" />

          <p class="text-caption font-weight-bold text-uppercase text-medium-emphasis tracking-normal mb-2">
            Tijden (optioneel)
          </p>
          <p class="text-caption text-medium-emphasis mb-4">
            Laat leeg om de start- en eindtijd van het gekozen tijdslot te gebruiken.
          </p>
          <VRow>
            <VCol
              cols="12"
              sm="4"
            >
              <AppTextField
                v-model="form.report_time"
                label="Rapporttijd"
                type="time"
                hide-details="auto"
                :error-messages="errors.report_time"
              />
            </VCol>
            <VCol
              cols="12"
              sm="4"
            >
              <AppTextField
                v-model="form.actual_start_time"
                label="Starttijd"
                type="time"
                hide-details="auto"
                :error-messages="errors.actual_start_time"
              />
            </VCol>
            <VCol
              cols="12"
              sm="4"
            >
              <AppTextField
                v-model="form.actual_end_time"
                label="Eindtijd"
                type="time"
                hide-details="auto"
                :error-messages="errors.actual_end_time"
              />
            </VCol>
          </VRow>

          <VDivider class="my-4" />

          <p class="text-caption font-weight-bold text-uppercase text-medium-emphasis tracking-normal mb-3">
            Capaciteit
          </p>
          <VRow>
            <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"
                hint="Vrijwilligers kunnen zelf boeken tot dit maximum"
                persistent-hint
                :rules="[requiredValidator]"
                :error-messages="errors.slots_open_for_claiming"
              />
            </VCol>
          </VRow>

          <VDivider class="my-4" />

          <p class="text-caption font-weight-bold text-uppercase text-medium-emphasis tracking-normal mb-3">
            Opties
          </p>
          <VRow>
            <VCol
              cols="12"
              md="6"
            >
              <VSwitch
                v-model="form.is_lead_role"
                color="primary"
                density="comfortable"
                label="Leidinggevende rol"
                hide-details
              />
            </VCol>
            <VCol
              cols="12"
              md="6"
            >
              <VSwitch
                v-model="form.allow_overlap"
                color="primary"
                density="comfortable"
                label="Overlap toegestaan"
                hide-details
              />
            </VCol>
          </VRow>
          <p class="text-caption text-medium-emphasis mb-0 mt-2">
            Leiding: coördinatie of verantwoordelijke. Overlap: dezelfde persoon mag meerdere shifts in hetzelfde tijdvak.
          </p>

          <VDivider class="my-4" />

          <p class="text-caption font-weight-bold text-uppercase text-medium-emphasis tracking-normal mb-3">
            Documentatie & status
          </p>
          <VRow>
            <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>

        <VDivider class="flex-shrink-0" />

        <VCardActions class="flex-shrink-0 px-6 py-4 bg-surface">
          <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>
