<script lang="ts" setup>
import type { FormError, FormSubmitEvent } from '@nuxt/ui'

import { isValidPhoneNumber, type PublicContact } from '~~/shared/auth'

type BookingMode = 'table' | 'pax'
type TicketType = 'vip' | 'supporter'

const toast = useToast()
const apiClient = useApiClient()

const eventDetails = [
  {
    label: 'Date',
    value: 'Saturday, 30 May 2026',
    icon: 'lucide:calendar-days'
  },
  {
    label: 'Time',
    value: '6:30 PM',
    icon: 'lucide:clock-6'
  },
  {
    label: 'Venue',
    value: "Yong Peng's Chee Ann Kor",
    icon: 'lucide:map-pin'
  }
] as const

const bookingModeOptions = [
  {
    value: 'table',
    label: 'Table (10 pax)'
  },
  {
    value: 'pax',
    label: 'Person'
  }
] satisfies Array<{ value: BookingMode, label: string }>

const ticketCatalog = [
  {
    value: 'vip',
    label: 'VIP',
    description: 'RM150 / pax',
    price: 150
  },
  {
    value: 'supporter',
    label: 'Supporter',
    description: 'RM60 / pax',
    price: 60
  }
] satisfies Array<{ value: TicketType, label: string, description: string, price: number }>

const contactsResponse = await apiClient<{ contacts: PublicContact[] }>('/api/public/contacts')
const personInCharge = computed(() => {
  return contactsResponse.contacts.map((contact) => ({
    label: contact.fullName,
    value: contact.id
  }))
})

const priceFormatter = new Intl.NumberFormat('en-MY', {
  style: 'currency',
  currency: 'MYR',
  minimumFractionDigits: 0,
  maximumFractionDigits: 0
})

const form = reactive({
  name: '',
  phone: '',
  bookingMode: 'table' as BookingMode,
  quantity: 1,
  ticketType: 'vip' as TicketType
})

const selectedPersonInCharge = ref(contactsResponse.contacts[0]?.id ?? '')

const selectedPersonInChargeRecord = computed(() => {
  return contactsResponse.contacts.find((contact) => contact.id === selectedPersonInCharge.value) ?? null
})

const selectedTicket = computed(() => {
  return ticketCatalog.find((ticket) => ticket.value === form.ticketType) ?? ticketCatalog[0]
})

const seatMultiplier = computed(() => form.bookingMode === 'table' ? 10 : 1)

const quantityLabel = computed(() => {
  return form.bookingMode === 'table' ? 'Number of tables' : 'Number of people'
})

const totalPrice = computed(() => form.quantity * seatMultiplier.value * selectedTicket.value.price)

const totalFormatted = computed(() => priceFormatter.format(totalPrice.value))

function validateBooking(state: typeof form): FormError[] {
  const errors: FormError[] = []

  if (!state.name.trim()) {
    errors.push({ name: 'name', message: 'Please enter the guest or organizer name.' })
  }

  if (!state.phone.trim()) {
    errors.push({ name: 'phone', message: 'Please enter a contact number.' })
  } else if (!isValidPhoneNumber(state.phone.trim())) {
    errors.push({ name: 'phone', message: 'Use a valid phone number with 8 to 15 digits.' })
  }

  if (state.quantity < 1) {
    errors.push({ name: 'quantity', message: 'Quantity must be at least 1.' })
  }

  return errors
}

function buildBookingMessage() {
  const bookingModeLabel = form.bookingMode === 'table' ? 'Table (10 pax each)' : 'Per person'

  return [
    "I'd like to book tickets for the DAP Johor 60th Anniversary Celebration.",
    '',
    `Name: ${form.name.trim()}`,
    `Phone Number: ${form.phone.trim()}`,
    `Booking Mode: ${bookingModeLabel}`,
    `Quantity: ${form.quantity}`,
    `Ticket Category: ${selectedTicket.value.label}`,
    `Seats Covered: ${form.quantity * seatMultiplier.value}`,
    `Total Price: ${totalFormatted.value}`
  ].join('\n')
}

function bookTicket(event: FormSubmitEvent<typeof form>) {
  const selectedPic = selectedPersonInChargeRecord.value

  if (!selectedPic) {
    toast.add({
      title: 'No person in charge available',
      description: 'Add a user with a phone number in the management page first.',
      color: 'error',
      icon: 'i-lucide-circle-alert'
    })
    return
  }

  const encodedMessage = encodeURIComponent(buildBookingMessage())
  const whatsappUrl = `https://wa.me/${selectedPic.phoneNumber}?text=${encodedMessage}`
  const bookingWindow = window.open(whatsappUrl, '_blank', 'noopener,noreferrer')

  if (!bookingWindow) {
    toast.add({
      title: 'WhatsApp could not be opened',
      description: 'Allow pop-ups for this site, then submit the booking again.',
      color: 'error',
      icon: 'i-lucide-circle-alert'
    })
    return
  }

  toast.add({
    title: 'WhatsApp booking draft opened',
    description: `Your reservation details were sent to ${selectedPic.fullName}.`,
    color: 'success',
    icon: 'i-lucide-check-circle-2'
  })

  event.preventDefault()
}
</script>

<template>
  <UContainer class="py-8">
    <div class="mx-auto max-w-2xl">
      <div class="mb-8 text-center">
        <h1 class="text-3xl font-extrabold tracking-tight text-highlighted sm:text-4xl">
          DAP JOHOR 60th Anniversary Celebration
        </h1>
      </div>

      <UCard id="booking-form" class="border border-default bg-default" :ui="{
        header: 'space-y-4',
        body: 'space-y-6'
      }">
        <template #header>
          <div class="space-y-3">
            <div v-for="detail in eventDetails" :key="detail.label"
              class="flex items-center gap-3 text-sm text-default">
              <UIcon :name="detail.icon" class="size-4 text-muted" />
              <span>{{ detail.value }}</span>
            </div>
          </div>
        </template>

        <UForm :state="form" :validate="validateBooking" class="space-y-6" @submit="bookTicket">
          <div class="space-y-5">
            <UFormField name="name" label="Name" required>
              <UInput v-model="form.name" size="xl" class="w-full" placeholder="e.g. John Doe" />
            </UFormField>

            <UFormField name="phone" label="Phone Number" required>
              <UInput v-model="form.phone" size="xl" type="tel" class="w-full" placeholder="e.g. 0123456789" />
            </UFormField>
          </div>

          <UFormField label="Booking Mode" name="bookingMode">
            <URadioGroup v-model="form.bookingMode" orientation="horizontal" variant="card" indicator="hidden"
              :items="bookingModeOptions" :ui="{
                fieldset: 'grid grid-cols-2 gap-3',
                item: 'rounded-xl border border-default bg-default p-3 data-[state=checked]:border-primary data-[state=checked]:bg-primary/5'
              }" />
          </UFormField>

          <UFormField :label="quantityLabel" name="quantity">
            <UInputNumber v-model="form.quantity" size="xl" class="w-full" :min="1" :step="1" />
          </UFormField>

          <UFormField label="Ticket Category" name="ticketType">
            <URadioGroup v-model="form.ticketType" orientation="horizontal" variant="card" indicator="hidden"
              :items="ticketCatalog" :ui="{
                fieldset: 'grid grid-cols-2 gap-3',
                item: 'rounded-xl border border-default bg-default p-3 data-[state=checked]:border-primary data-[state=checked]:bg-primary/5'
              }" />
          </UFormField>

          <div class="rounded-xl border border-default bg-muted px-4 py-4">
            <div class="flex items-center justify-between gap-4">
              <span class="text-sm font-medium text-muted">Total Price</span>
              <span class="text-2xl font-bold text-highlighted">{{ totalFormatted }}</span>
            </div>
          </div>

          <UFormField label="Person In Charge">
            <USelect
              v-model="selectedPersonInCharge"
              size="xl"
              class="w-full"
              :items="personInCharge"
              :disabled="!personInCharge.length"
            />
          </UFormField>

          <UButton id="getTicketBtn" type="submit" label="Book Your Ticket Now" size="xl"
            class="w-full justify-center" :disabled="!selectedPersonInCharge" />
        </UForm>
      </UCard>
    </div>
  </UContainer>
</template>
