<script setup lang="ts">
import axios from 'axios'
import { useEventDetail, useEventChildren, useTransitionEventStatus } from '@/composables/api/useEvents'
import { dutchPlural } from '@/lib/dutch-plural'
import { eventStatusLabelNl, transitionVisualKind } from '@/lib/event-status'
import { useAuthStore } from '@/stores/useAuthStore'
import { useNotificationStore } from '@/stores/useNotificationStore'
import { useOrganisationStore } from '@/stores/useOrganisationStore'
import EditEventDialog from '@/components/events/EditEventDialog.vue'
import RegistrationLinkCard from '@/components/events/RegistrationLinkCard.vue'
import type { EventStatus } from '@/types/event'

const route = useRoute()
const authStore = useAuthStore()
const orgStore = useOrganisationStore()
const notificationStore = useNotificationStore()

const orgId = computed(() => authStore.currentOrganisation?.id ?? '')
const eventId = computed(() => String((route.params as { id: string }).id))

const { data: event, isLoading, isError, refetch } = useEventDetail(orgId, eventId)

const {
  mutateAsync: transitionEventStatus,
  isPending: isTransitionPending,
} = useTransitionEventStatus(orgId, eventId)

const confirmTransitionOpen = ref(false)
const pendingTransitionStatus = ref<EventStatus | null>(null)

const allowedTransitions = computed(() => event.value?.allowed_transitions ?? [])

function transitionButtonColor(current: EventStatus, target: EventStatus): string {
  const kind = transitionVisualKind(current, target)
  if (kind === 'dangerous')
    return 'error'
  if (kind === 'backward')
    return 'secondary'
  return 'primary'
}

function transitionButtonVariant(current: EventStatus, target: EventStatus): 'flat' | 'outlined' {
  return transitionVisualKind(current, target) === 'backward' ? 'outlined' : 'flat'
}

function openTransitionConfirm(target: EventStatus) {
  pendingTransitionStatus.value = target
  confirmTransitionOpen.value = true
}

function cancelTransitionConfirm() {
  confirmTransitionOpen.value = false
  pendingTransitionStatus.value = null
}

function transition422Message(err: unknown): string {
  if (!axios.isAxiosError(err))
    return ''

  const body = err.response?.data as { message?: string; errors?: string[] } | undefined
  if (body?.errors?.length)
    return body.errors.join(' ')
  if (body?.message)
    return body.message

  return ''
}

async function confirmTransition() {
  const target = pendingTransitionStatus.value
  if (!target)
    return

  try {
    await transitionEventStatus(target)
    notificationStore.show('De status is bijgewerkt.', 'success')
    cancelTransitionConfirm()
  }
  catch (err) {
    if (axios.isAxiosError(err) && err.response?.status === 422) {
      const msg = transition422Message(err)
      notificationStore.show(msg || 'Status wijzigen is op dit moment niet mogelijk.', 'error')
    }
    else {
      notificationStore.show('Status wijzigen is mislukt. Probeer het opnieuw.', 'error')
    }
  }
}

// Children count for programmaonderdelen badge — only for festivals
const { data: children } = useEventChildren(orgId, eventId)

// Set active event in store
watch(eventId, (id) => {
  if (id) orgStore.setActiveEvent(id)
}, { immediate: true })

const isEditDialogOpen = ref(false)

const statusColor: Record<EventStatus, string> = {
  draft: 'default',
  published: 'info',
  registration_open: 'cyan',
  buildup: 'warning',
  showday: 'success',
  teardown: 'warning',
  closed: 'error',
}

const eventTypeColor: Record<string, string> = {
  festival: 'purple',
  series: 'info',
}

const dateFormatter = new Intl.DateTimeFormat('nl-NL', {
  day: '2-digit',
  month: '2-digit',
  year: 'numeric',
})

function formatDate(iso: string) {
  return dateFormatter.format(new Date(iso))
}

const baseTabs = [
  { label: 'Overzicht', icon: 'tabler-layout-dashboard', route: 'events-id' },
  { label: 'Personen', icon: 'tabler-users', route: 'events-id-persons' },
  { label: 'Publiekslijsten', icon: 'tabler-list', route: 'events-id-crowd-lists' },
  { label: 'Tijdsloten', icon: 'tabler-clock', route: 'events-id-time-slots' },
  { label: 'Secties & Shifts', icon: 'tabler-layout-grid', route: 'events-id-sections' },
  { label: 'Artiesten', icon: 'tabler-music', route: 'events-id-artists' },
  { label: 'Briefings', icon: 'tabler-mail', route: 'events-id-briefings' },
  { label: 'Instellingen', icon: 'tabler-settings', route: 'events-id-settings' },
]

const programmaonderdelenLabel = computed(() => {
  const label = event.value?.sub_event_label
    ? dutchPlural(event.value.sub_event_label)
    : 'Programmaonderdelen'
  const count = children.value?.length ?? event.value?.children_count ?? 0
  return `${label} (${count})`
})

const tabs = computed(() => {
  if (!event.value?.is_festival) return baseTabs

  // Festival tab order: Overzicht | Programmaonderdelen | Tijdsloten | Secties & Shifts | Personen | Publiekslijsten | Artiesten | Briefings | Instellingen
  const festivalTab = {
    label: programmaonderdelenLabel.value,
    icon: 'tabler-calendar-event',
    route: 'events-id-programmaonderdelen',
  }

  return [
    baseTabs[0], // Overzicht
    festivalTab,
    baseTabs[3], // Tijdsloten
    baseTabs[4], // Secties & Shifts
    baseTabs[1], // Personen
    baseTabs[2], // Publiekslijsten
    baseTabs[5], // Artiesten
    baseTabs[6], // Briefings
    baseTabs[7], // Instellingen
  ]
})

const activeTab = computed(() => {
  const name = route.name as string
  return tabs.value.find(t => name === t.route || name?.startsWith(`${t.route}-`))?.route ?? 'events-id'
})

const backRoute = computed(() => {
  if (event.value?.is_sub_event && event.value.parent_event_id) {
    return { name: 'events-id' as const, params: { id: event.value.parent_event_id } }
  }
  return { name: 'events' as const }
})
</script>

<template>
  <div>
    <!-- Loading -->
    <VSkeletonLoader
      v-if="isLoading"
      type="card"
    />

    <!-- Error -->
    <VAlert
      v-else-if="isError"
      type="error"
      class="mb-4"
    >
      Kon evenement niet laden.
      <template #append>
        <VBtn
          variant="text"
          @click="refetch()"
        >
          Opnieuw proberen
        </VBtn>
      </template>
    </VAlert>

    <template v-else-if="event">
      <!-- Header -->
      <div class="d-flex flex-wrap justify-space-between align-center gap-y-4 mb-6">
        <div class="d-flex flex-wrap align-center gap-x-3 gap-y-2">
          <VBtn
            icon="tabler-arrow-left"
            variant="text"
            :to="backRoute"
          />
          <h4 class="text-h4">
            <template v-if="event.is_sub_event && event.parent && event.parent_event_id">
              <RouterLink
                :to="{ name: 'events-id', params: { id: event.parent_event_id } }"
                class="text-medium-emphasis text-decoration-none"
              >
                {{ event.parent.name }}
              </RouterLink>
              <span class="text-medium-emphasis mx-1">&raquo;</span>
            </template>
            {{ event.name }}
          </h4>
          <VChip
            v-if="event.event_type === 'festival' || event.event_type === 'series'"
            :color="eventTypeColor[event.event_type]"
            size="small"
            variant="tonal"
          >
            {{ event.event_type_label ?? (event.event_type === 'festival' ? 'Festival' : 'Serie') }}
          </VChip>
          <VChip
            :color="statusColor[event.status]"
            size="small"
          >
            {{ eventStatusLabelNl(event.status) }}
          </VChip>
          <div
            v-if="allowedTransitions.length"
            class="d-flex flex-wrap align-center gap-2"
          >
            <VBtn
              v-for="target in allowedTransitions"
              :key="target"
              size="small"
              :color="transitionButtonColor(event.status, target)"
              :variant="transitionButtonVariant(event.status, target)"
              :disabled="isTransitionPending"
              @click="openTransitionConfirm(target)"
            >
              {{ eventStatusLabelNl(target) }}
            </VBtn>
          </div>
          <span class="text-body-1 text-disabled">
            {{ formatDate(event.start_date) }} – {{ formatDate(event.end_date) }}
          </span>
        </div>
        <VBtn
          prepend-icon="tabler-edit"
          @click="isEditDialogOpen = true"
        >
          Bewerken
        </VBtn>
      </div>

      <VDialog
        v-model="confirmTransitionOpen"
        max-width="440"
      >
        <VCard>
          <VCardTitle class="text-h6">
            Status wijzigen
          </VCardTitle>
          <VCardText class="text-body-1">
            Weet je zeker dat je de status wilt wijzigen naar
            <strong>{{ pendingTransitionStatus ? eventStatusLabelNl(pendingTransitionStatus) : '' }}</strong>?
          </VCardText>
          <VCardActions>
            <VSpacer />
            <VBtn
              variant="text"
              :disabled="isTransitionPending"
              @click="cancelTransitionConfirm"
            >
              Annuleren
            </VBtn>
            <VBtn
              :color="pendingTransitionStatus && transitionVisualKind(event.status, pendingTransitionStatus) === 'dangerous' ? 'error' : 'primary'"
              :loading="isTransitionPending"
              @click="confirmTransition"
            >
              Bevestigen
            </VBtn>
          </VCardActions>
        </VCard>
      </VDialog>

      <!-- Registration link (top-level events only) -->
      <RegistrationLinkCard
        v-if="!event.parent_event_id"
        :event="event"
      />

      <!-- Horizontal tabs -->
      <VTabs
        :model-value="activeTab"
        class="mb-6"
      >
        <VTab
          v-for="tab in tabs"
          :key="tab.route"
          :value="tab.route"
          :prepend-icon="tab.icon"
          :to="{ name: tab.route, params: { id: eventId } }"
        >
          {{ tab.label }}
        </VTab>
      </VTabs>

      <!-- Tab content -->
      <slot :event="event" />

      <EditEventDialog
        v-model="isEditDialogOpen"
        :event="event"
        :org-id="orgId"
      />
    </template>
  </div>
</template>
