<script lang="ts" setup>
import type { PublicBooking } from '~~/shared/booking'

import {
  formatBookingCurrency,
  getBookingModeLabel,
  getBookingStatusLabel,
  getTicketCatalogItem
} from '~~/shared/booking'

import { getErrorMessage } from '../../utils/errors'
import { formatDateTime } from '../../utils/formatters'

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

const token = String(route.params.token || '')
const confirming = ref(false)

let initialBooking: PublicBooking

try {
  const response = await apiClient<{ booking: PublicBooking }>(`/api/public/bookings/${token}`)
  initialBooking = response.booking
} catch (error: any) {
  throw createError({
    statusCode: error?.statusCode || error?.data?.statusCode || 404,
    statusMessage: error?.data?.statusMessage || error?.message || 'Booking not found'
  })
}

const booking = ref(initialBooking)

const statusColor = computed(() => booking.value.status === 'confirmed' ? 'success' : 'warning')
const ticketLabel = computed(() => getTicketCatalogItem(booking.value.ticketType)?.label || booking.value.ticketType.toUpperCase())
const totalFormatted = computed(() => formatBookingCurrency(booking.value.totalPrice))
const detailRows = computed(() => {
  const rows = [
    {
      label: 'Guest / Organizer',
      value: booking.value.customerName
    },
    {
      label: 'Contact Number',
      value: booking.value.customerPhone
    },
    {
      label: 'Person In Charge',
      value: booking.value.personInChargeName
    },
    {
      label: 'PIC Phone',
      value: booking.value.personInChargePhoneNumber
    },
    {
      label: 'Booking Mode',
      value: getBookingModeLabel(booking.value.bookingMode)
    },
    {
      label: 'Ticket Category',
      value: ticketLabel.value
    },
    {
      label: 'Quantity',
      value: String(booking.value.quantity)
    },
    {
      label: 'Seats Covered',
      value: String(booking.value.seatCount)
    },
    {
      label: 'Submitted',
      value: formatDateTime(booking.value.createdAt)
    }
  ]

  if (booking.value.confirmedAt) {
    rows.push({
      label: 'Confirmed At',
      value: formatDateTime(booking.value.confirmedAt)
    })
  }

  return rows
})

async function confirmBooking() {
  if (booking.value.status === 'confirmed') {
    return
  }

  confirming.value = true

  try {
    const response = await apiClient<{ booking: PublicBooking, alreadyConfirmed: boolean }>(
      `/api/public/bookings/${token}/confirm`,
      {
        method: 'POST'
      }
    )

    booking.value = response.booking

    toast.add({
      title: response.alreadyConfirmed ? 'Booking already confirmed' : 'Booking confirmed',
      description: response.alreadyConfirmed
        ? 'This booking had already been confirmed earlier.'
        : 'The booking details have been confirmed successfully.',
      color: 'success',
      icon: 'i-lucide-check-circle-2'
    })
  } catch (error) {
    toast.add({
      title: 'Confirmation failed',
      description: getErrorMessage(error, 'Please try again in a moment.'),
      color: 'error',
      icon: 'i-lucide-circle-alert'
    })
  } finally {
    confirming.value = false
  }
}
</script>

<template>
  <UContainer class="py-8">
    <div class="mx-auto max-w-3xl space-y-5">
      <div class="space-y-2 text-center">
        <UBadge label="PIC Confirmation" color="primary" variant="soft" class="rounded-full" />
        <h1 class="text-2xl font-bold tracking-tight text-highlighted sm:text-3xl">
          Review Booking Details
        </h1>
        <p class="text-sm text-muted">
          Confirm the booking after verifying the details below.
        </p>
      </div>

      <UCard
        class="border border-default bg-default shadow-sm"
        :ui="{ body: 'space-y-4 p-4 sm:p-5' }"
      >
        <div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div class="space-y-1">
            <p class="text-xs font-medium uppercase tracking-wide text-muted">
              Booking status
            </p>
            <UBadge :label="getBookingStatusLabel(booking.status)" :color="statusColor" variant="soft" />
          </div>

          <div class="text-sm text-muted">
            Submitted {{ formatDateTime(booking.createdAt) }}
          </div>
        </div>

        <UAlert
          v-if="booking.status === 'confirmed'"
          title="Booking already confirmed"
          :description="`Confirmed on ${formatDateTime(booking.confirmedAt)}.`"
          color="success"
          icon="i-lucide-badge-check"
        />

        <div class="overflow-hidden rounded-xl border border-default">
          <div
            v-for="row in detailRows"
            :key="row.label"
            class="grid grid-cols-[8.5rem_minmax(0,1fr)] gap-3 border-b border-default px-4 py-3 text-sm last:border-b-0 sm:grid-cols-[11rem_minmax(0,1fr)]"
          >
            <div class="text-xs font-medium uppercase tracking-wide text-muted sm:text-sm sm:normal-case sm:tracking-normal">
              {{ row.label }}
            </div>
            <div class="min-w-0 font-medium text-highlighted break-words">
              {{ row.value }}
            </div>
          </div>

          <div class="grid grid-cols-[8.5rem_minmax(0,1fr)] gap-3 bg-primary/5 px-4 py-3 sm:grid-cols-[11rem_minmax(0,1fr)]">
            <div class="text-xs font-semibold uppercase tracking-wide text-primary sm:text-sm sm:normal-case sm:tracking-normal">
              Total Price
            </div>
            <div class="min-w-0 text-lg font-bold text-highlighted sm:text-xl">
              {{ totalFormatted }}
            </div>
          </div>
        </div>

        <div class="flex flex-col-reverse gap-3 sm:flex-row sm:justify-end">
          <UButton
            to="/"
            label="Back To Booking Form"
            color="neutral"
            variant="ghost"
            class="justify-center"
          />

          <UButton
            label="Confirm This Booking"
            icon="i-lucide-check-check"
            class="justify-center"
            :disabled="booking.status === 'confirmed'"
            :loading="confirming"
            @click="confirmBooking"
          />
        </div>
      </UCard>
    </div>
  </UContainer>
</template>
