<script setup>
import { AnimatePresence, motion } from 'motion-v'
import {
  AlertCircle,
  ArrowLeft,
  Lock,
  Star,
  ThumbsUp,
} from 'lucide-vue-next'
import CheckoutDocumentCard from '~/components/checkout/CheckoutDocumentCard.vue'
import CheckoutProgress from '~/components/checkout/CheckoutProgress.vue'
import CheckoutSummary from '~/components/checkout/CheckoutSummary.vue'
import OfferContextBanner from '~/components/offers/OfferContextBanner.vue'
import { useCheckoutDocuments, useCheckoutSteps } from '~/constants/checkout-ui'
import { resolveOfferForVehicleGroupId, useOffersContent } from '~/content/offers'
import { resolvePublicApiError } from '~/content/utils'
import { buildExtrasPayload, parseExtrasQuery } from '~/utils/public-booking-extras'
import { buildRentExtrasRoute, buildRentSearchRoute, buildTrackRoute } from '~/utils/public-routes'

const route = useRoute()
const offersContent = useOffersContent()
const { currency } = usePublicPreferences()
const { locale } = usePublicLocale()
const ui = usePublicUi()
const { activeOfferSlug } = usePublicOfferContext()
const { buildCatalogPayload, parseSearchQuery } = useSearchCatalog()
const { createBooking, fetchQuote } = usePublicBooking()
const checkoutSteps = useCheckoutSteps()
const checkoutDocuments = useCheckoutDocuments()

const currentStep = ref(0)
const isLoadingQuote = ref(false)
const isProcessing = ref(false)
const quoteError = ref('')
const submitError = ref('')
const submitAttempted = ref(false)
const quoteData = ref(null)
const selectedExtraIds = computed(() => parseExtrasQuery(route.query.extras))
const offerCards = computed(() => offersContent.offerCards.value || [])
const resolvedOfferBySlug = offersContent.useResolvedOffer(activeOfferSlug)
const activeOffer = computed(() => {
  if (resolvedOfferBySlug.value) {
    return resolvedOfferBySlug.value
  }

  const groupId = Number(route.params.id || 0)
  return resolveOfferForVehicleGroupId(offerCards.value, groupId)
})

const documents = reactive({
  license: null,
  passport: null,
})

const formData = reactive({
  firstName: '',
  lastName: '',
  email: '',
})
const {
  combinePhone,
  handlePhoneChange,
  handlePhoneCountryCodeChange,
  isPhoneValid,
  phoneCountryCode,
  phoneNumber,
} = useInternationalPhone()

const hasRequiredTripQuery = computed(() => {
  return Boolean(route.query.pickupLocationId && route.query.pickupAt && route.query.dropoffAt)
})

const vehicleGroupId = computed(() => {
  const numericId = Number(route.params.id || 0)
  return numericId > 0 ? numericId : null
})

const vehicleId = computed(() => {
  const numericId = Number(route.query.vehicleId || 0)
  return numericId > 0 ? numericId : null
})

const parsedTrip = computed(() => {
  if (!hasRequiredTripQuery.value) {
    return null
  }

  return parseSearchQuery(route.query)
})

const quotePayload = computed(() => {
  if (!vehicleGroupId.value || !parsedTrip.value) {
    return null
  }

  return {
    ...buildCatalogPayload({
      pickupLocationId: Number(route.query.pickupLocationId),
      dropoffLocationId: Number(route.query.dropoffLocationId || route.query.pickupLocationId),
      pickupDate: parsedTrip.value.pickupDate,
      dropoffDate: parsedTrip.value.dropoffDate,
      pickupTime: parsedTrip.value.pickupTime,
      dropoffTime: parsedTrip.value.dropoffTime,
      currency: currency.value,
      promoCode: String(route.query.promoCode || ''),
      offerSlug: activeOffer.value?.slug || activeOfferSlug.value || undefined,
    }),
    vehicle_group_id: vehicleGroupId.value,
    extras: buildExtrasPayload(selectedExtraIds.value),
  }
})

const isEmailValid = computed(() => {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email.trim())
})

const isStep0Valid = computed(() => {
  return (
    formData.firstName.trim() !== ''
    && formData.lastName.trim() !== ''
    && isEmailValid.value
    && isPhoneValid.value
  )
})

function fieldClass(value, invalid = false) {
  const hasError = submitAttempted.value && (String(value || '').trim() === '' || invalid)
  return hasError
    ? 'border-red-300 focus:ring-red-200 focus:border-red-400'
    : 'border-white/60 focus:ring-brand-orange/50 focus:border-brand-orange'
}

const actionLabel = computed(() => {
  if (currentStep.value < checkoutSteps.value.length - 1) {
    return ui.value.common.continue
  }

  return ui.value.common.confirmReservation
})

watch(
  isStep0Valid,
  (value) => {
    if (value && submitError.value === ui.value.common.fillRequiredFields && currentStep.value === 0) {
      submitError.value = ''
    }
  },
)

const quoteGroup = computed(() => quoteData.value?.group || quoteData.value || null)
const quoteSummary = computed(() => quoteData.value?.quote || null)
const vehicleDisplayName = computed(() => {
  const make = quoteGroup.value?.model?.make || quoteGroup.value?.vehicle?.make || ''
  const model = quoteGroup.value?.model?.name || quoteGroup.value?.vehicle?.model || quoteGroup.value?.name || ''

  return [make, model].filter(Boolean).join(' ').trim() || 'Bent'
})

async function loadQuote() {
  if (import.meta.server) {
    return
  }

  if (!quotePayload.value) {
    return
  }

  isLoadingQuote.value = true
  quoteError.value = ''

  try {
    quoteData.value = await fetchQuote(quotePayload.value)
  } catch (error) {
    console.error('Failed to load checkout quote', error)
    quoteData.value = null
    quoteError.value = resolvePublicApiError(error, ui.value.checkout.couldNotPrepare, locale.value)
  } finally {
    isLoadingQuote.value = false
  }
}

async function goBack() {
  if (currentStep.value > 0) {
    currentStep.value -= 1
    return
  }

  await navigateTo(buildRentExtrasRoute(vehicleGroupId.value, route.query, {
    locale: locale.value,
  }))
}

async function handleNext() {
  submitError.value = ''

  if (currentStep.value === 0 && !isStep0Valid.value) {
    submitAttempted.value = true
    submitError.value = ui.value.common.fillRequiredFields
    return
  }

  if (currentStep.value < checkoutSteps.value.length - 1) {
    currentStep.value += 1
    return
  }

  if (!quotePayload.value || !vehicleGroupId.value || !vehicleId.value) {
    submitError.value = ui.value.checkout.incompleteContext
    return
  }

  isProcessing.value = true

  try {
    const booking = await createBooking({
      service_type: 'rental',
      vehicle_group_id: vehicleGroupId.value,
      vehicle_id: vehicleId.value,
      pickup_location_id: Number(route.query.pickupLocationId),
      dropoff_location_id: Number(route.query.dropoffLocationId || route.query.pickupLocationId),
      pickup_at: quotePayload.value.pickup_at,
      dropoff_at: quotePayload.value.dropoff_at,
      currency: quotePayload.value.currency,
      promo_code: quotePayload.value.promo_code,
      offer_slug: activeOffer.value?.slug || activeOfferSlug.value || undefined,
      extras: buildExtrasPayload(selectedExtraIds.value),
        customer: {
        first_name: formData.firstName.trim(),
        last_name: formData.lastName.trim(),
        email: formData.email.trim(),
        phone: combinePhone(),
      },
      customer_documents: {
        license: documents.license || undefined,
        passport: documents.passport || undefined,
      },
    })

    const token = booking?.public_portal_token

    if (!token) {
      throw new Error('Booking was created without a public portal token.')
    }

    await navigateTo(buildTrackRoute(token, {}, {
      locale: locale.value,
    }))
  } catch (error) {
    console.error('Failed to submit public booking', error)
    submitError.value = resolvePublicApiError(error, ui.value.checkout.couldNotComplete, locale.value)
  } finally {
    isProcessing.value = false
  }
}

watch(
  quotePayload,
  async () => {
    if (!quotePayload.value) {
      return
    }

    await loadQuote()
  },
  { immediate: true },
)

watch(
  currentStep,
  () => {
    if (import.meta.client) {
      window.scrollTo({ left: 0, top: 0, behavior: 'smooth' })
    }
  },
)

onMounted(() => {
  if (import.meta.client) {
    window.scrollTo({ left: 0, top: 0, behavior: 'auto' })
  }
})
</script>

<template>
  <div class="min-h-screen text-slate-900 font-sans pb-24 selection:bg-brand-orange/30 relative">
    <div class="fixed top-[-10%] left-[-10%] w-[40%] h-[40%] rounded-full bg-brand-orange/5 blur-[120px] pointer-events-none" />
    <div class="fixed bottom-[-10%] right-[-10%] w-[40%] h-[40%] rounded-full bg-blue-500/5 blur-[120px] pointer-events-none" />

    <main class="container mx-auto px-4 max-w-6xl pt-6 md:pt-8 relative z-10">
      <div class="flex items-center justify-between gap-4 mb-6 md:mb-8">
        <button
          type="button"
          class="inline-flex items-center gap-3 text-slate-600 hover:text-slate-900 font-medium transition-all group"
          @click="goBack"
        >
          <div class="w-10 h-10 rounded-full bg-white/70 backdrop-blur-md border border-white/80 shadow-sm flex items-center justify-center group-hover:bg-white group-hover:scale-105 transition-all">
            <ArrowLeft class="w-5 h-5" />
          </div>
          <span class="tracking-wide">{{ ui.common.back }}</span>
        </button>

        <div class="hidden sm:inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/70 backdrop-blur-md border border-white/80 shadow-sm">
          <Lock class="w-4 h-4 text-emerald-500" />
          <span class="text-sm font-bold text-slate-900">{{ ui.checkout.reservationRequest }}</span>
        </div>
      </div>

      <div v-if="!hasRequiredTripQuery || !vehicleGroupId || quoteError" class="max-w-2xl mx-auto">
        <div class="bg-white/70 backdrop-blur-2xl rounded-[2.5rem] p-8 md:p-12 shadow-[0_8px_30px_rgb(0,0,0,0.04)] border border-white/50">
          <div class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-red-50 text-red-500 text-xs font-bold uppercase tracking-widest mb-4">
            <AlertCircle class="w-3.5 h-3.5" />
            {{ ui.checkout.unavailableEyebrow }}
          </div>
          <h1 class="text-3xl font-display font-bold text-slate-900 mb-3">{{ ui.checkout.couldNotPrepareTitle }}</h1>
          <p class="text-slate-500 mb-8">
            {{ quoteError || ui.checkout.missingTripDetails }}
          </p>
          <button
            type="button"
            class="px-8 py-4 bg-slate-900 text-white rounded-2xl font-bold hover:bg-brand-orange transition-all"
            @click="navigateTo(buildRentSearchRoute(route.query, { locale }))"
          >
            {{ ui.common.backToSearch }}
          </button>
        </div>
      </div>

      <div v-else-if="isLoadingQuote || !quoteSummary || !quoteGroup" class="max-w-2xl mx-auto">
        <div class="bg-white/70 backdrop-blur-2xl rounded-[2.5rem] p-8 md:p-12 shadow-[0_8px_30px_rgb(0,0,0,0.04)] border border-white/50 text-center">
          <motion.div
            :animate="{ rotate: 360 }"
            :transition="{ duration: 1, repeat: Infinity, ease: 'linear' }"
            class="w-12 h-12 border-4 border-brand-orange/20 border-t-brand-orange rounded-full mx-auto mb-6"
          />
          <h1 class="text-3xl font-display font-bold text-slate-900 mb-3">{{ ui.checkout.preparing }}</h1>
          <p class="text-slate-500">{{ ui.checkout.liveLockingDescription }}</p>
        </div>
      </div>

      <div v-else class="grid grid-cols-1 lg:grid-cols-12 lg:items-start gap-8 lg:gap-12">
        <div class="lg:col-span-7 xl:col-span-8">
          <CheckoutProgress :current-step="currentStep" :steps="checkoutSteps" />

          <div class="bg-white/60 backdrop-blur-2xl rounded-[2.5rem] p-8 md:p-12 shadow-[0_8px_30px_rgb(0,0,0,0.04)] border border-white/50 relative overflow-hidden">
            <AnimatePresence mode="wait">
              <motion.div
                v-if="currentStep === 0"
                key="step-details"
                :initial="{ opacity: 0, x: 20 }"
                :animate="{ opacity: 1, x: 0 }"
                :exit="{ opacity: 0, x: -20 }"
                class="space-y-8"
              >
                <div>
                  <div class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-brand-orange/10 text-brand-orange text-xs font-bold uppercase tracking-widest mb-4">
                    <Star class="w-3.5 h-3.5" /> {{ ui.checkout.detailsBadge }}
                  </div>
                  <h2 class="text-3xl font-display font-bold text-slate-900 mb-2">{{ ui.checkout.title }}</h2>
                  <p class="text-slate-500">{{ ui.checkout.detailsDescriptionTemplate.replace('{vehicle}', vehicleDisplayName) }}</p>
                </div>

                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                  <div class="space-y-2">
                    <label class="text-xs font-bold uppercase tracking-widest text-slate-400 ml-2">{{ ui.checkout.firstName }}</label>
                    <input
                      v-model="formData.firstName"
                      :class="['w-full bg-white/50 backdrop-blur-sm rounded-2xl px-5 py-4 text-slate-900 font-medium shadow-[0_2px_10px_rgba(0,0,0,0.02)] focus:bg-white focus:ring-2 outline-none transition-all placeholder:text-slate-300', fieldClass(formData.firstName)]"
                      :placeholder="ui.checkout.firstNamePlaceholder"
                      type="text"
                    >
                  </div>

                  <div class="space-y-2">
                    <label class="text-xs font-bold uppercase tracking-widest text-slate-400 ml-2">{{ ui.checkout.lastName }}</label>
                    <input
                      v-model="formData.lastName"
                      :class="['w-full bg-white/50 backdrop-blur-sm rounded-2xl px-5 py-4 text-slate-900 font-medium shadow-[0_2px_10px_rgba(0,0,0,0.02)] focus:bg-white focus:ring-2 outline-none transition-all placeholder:text-slate-300', fieldClass(formData.lastName)]"
                      :placeholder="ui.checkout.lastNamePlaceholder"
                      type="text"
                    >
                  </div>

                  <div class="space-y-2">
                    <label class="text-xs font-bold uppercase tracking-widest text-slate-400 ml-2">{{ ui.checkout.emailAddress }}</label>
                    <input
                      v-model="formData.email"
                      :class="['w-full bg-white/50 backdrop-blur-sm rounded-2xl px-5 py-4 text-slate-900 font-medium shadow-[0_2px_10px_rgba(0,0,0,0.02)] focus:bg-white focus:ring-2 outline-none transition-all placeholder:text-slate-300', fieldClass(formData.email, formData.email && !isEmailValid)]"
                      :placeholder="ui.checkout.emailPlaceholder"
                      type="email"
                    >
                    <p v-if="submitAttempted && (formData.email.trim() === '' || !isEmailValid)" class="text-xs text-red-500 ml-2 mt-1">
                      {{ ui.checkout.emailError }}
                    </p>
                  </div>

                  <div class="space-y-2">
                    <label class="text-xs font-bold uppercase tracking-widest text-slate-400 ml-2">{{ ui.checkout.phoneNumber }}</label>
                    <div class="grid grid-cols-[6rem_minmax(0,1fr)] gap-3">
                      <input
                        :value="phoneCountryCode"
                        :class="['w-full bg-white/50 backdrop-blur-sm rounded-2xl px-4 py-4 text-slate-900 font-medium shadow-[0_2px_10px_rgba(0,0,0,0.02)] focus:bg-white focus:ring-2 outline-none transition-all placeholder:text-slate-300 text-center', fieldClass(phoneCountryCode, phoneCountryCode === '+')]"
                        placeholder="+995"
                        type="tel"
                        inputmode="tel"
                        autocomplete="tel-country-code"
                        required
                        @input="handlePhoneCountryCodeChange"
                      >
                      <input
                        :value="phoneNumber"
                        :class="['w-full bg-white/50 backdrop-blur-sm rounded-2xl px-5 py-4 text-slate-900 font-medium shadow-[0_2px_10px_rgba(0,0,0,0.02)] focus:bg-white focus:ring-2 outline-none transition-all placeholder:text-slate-300', fieldClass(phoneNumber, phoneNumber && !isPhoneValid)]"
                        :placeholder="ui.checkout.phonePlaceholder"
                        type="tel"
                        inputmode="tel"
                        autocomplete="tel-national"
                        @input="handlePhoneChange"
                    >
                    </div>
                    <p v-if="submitAttempted && (!phoneNumber || !isPhoneValid)" class="text-xs text-red-500 ml-2 mt-1">
                      {{ ui.checkout.phoneError }}
                    </p>
                  </div>
                </div>
              </motion.div>

              <motion.div
                v-else-if="currentStep === 1"
                key="step-documents"
                :initial="{ opacity: 0, x: 20 }"
                :animate="{ opacity: 1, x: 0 }"
                :exit="{ opacity: 0, x: -20 }"
                class="space-y-8"
              >
                <div>
                  <div class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-blue-500/10 text-blue-600 text-xs font-bold uppercase tracking-widest mb-4">
                    <ThumbsUp class="w-3.5 h-3.5" /> {{ ui.checkout.documentsBadge }}
                  </div>
                  <h2 class="text-3xl font-display font-bold text-slate-900 mb-2">{{ ui.checkout.requiredDocuments }}</h2>
                  <p class="text-slate-500">{{ ui.checkout.requiredDocumentsHint }}</p>
                </div>

                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                  <CheckoutDocumentCard
                    v-for="item in checkoutDocuments"
                    :key="item.key"
                    v-model="documents[item.key]"
                    :description="item.description"
                    :title="item.title"
                  />
                </div>

                <div class="bg-amber-50/80 backdrop-blur-sm rounded-2xl p-4 flex gap-3 text-amber-700 text-sm font-medium border border-amber-100/50">
                  <AlertCircle class="w-5 h-5 shrink-0" />
                  <p>{{ ui.checkout.requiredDocumentsSkip }}</p>
                </div>
              </motion.div>

              <motion.div
                v-else
                key="step-confirmation"
                :initial="{ opacity: 0, x: 20 }"
                :animate="{ opacity: 1, x: 0 }"
                :exit="{ opacity: 0, x: -20 }"
                class="space-y-8"
              >
                <div>
                  <div class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-emerald-500/10 text-emerald-600 text-xs font-bold uppercase tracking-widest mb-4">
                    <Lock class="w-3.5 h-3.5" /> {{ ui.checkout.reviewBadge }}
                  </div>
                  <h2 class="text-3xl font-display font-bold text-slate-900 mb-2">{{ ui.checkout.finalStep }}</h2>
                  <p class="text-slate-500">{{ ui.checkout.reviewDescription }}</p>
                </div>

                <div class="bg-white/50 backdrop-blur-sm rounded-[2rem] border border-white/60 shadow-[0_2px_10px_rgba(0,0,0,0.02)] p-6 md:p-7 space-y-4">
                  <div class="flex items-start gap-4">
                    <div class="w-12 h-12 rounded-xl bg-emerald-50 text-emerald-600 border border-emerald-100 flex items-center justify-center shrink-0">
                      <Lock class="w-6 h-6" />
                    </div>

                    <div class="space-y-2">
                      <h3 class="font-bold text-slate-900 text-lg">{{ ui.checkout.paymentAfterApproval }}</h3>
                      <p class="text-sm text-slate-500 leading-relaxed">
                        {{ ui.checkout.paymentAfterApprovalDescription }}
                      </p>
                    </div>
                  </div>

                  <div class="rounded-2xl bg-slate-900/[0.03] border border-slate-200/70 px-4 py-4 text-sm text-slate-600">
                    {{ ui.checkout.keepzTarget }}
                  </div>
                </div>
              </motion.div>
            </AnimatePresence>

            <div v-if="submitError" class="mt-8 bg-red-50/80 backdrop-blur-sm rounded-2xl p-4 flex gap-3 text-red-600 text-sm font-medium border border-red-100/70">
              <AlertCircle class="w-5 h-5 shrink-0" />
              <p>{{ submitError }}</p>
            </div>

            <div class="mt-10 pt-8 border-t border-white/50 flex justify-end">
              <button
                type="button"
                :disabled="isProcessing"
                class="px-10 py-4 bg-brand-orange text-white rounded-2xl font-bold text-lg hover:bg-[#E66000] hover:shadow-[0_8px_24px_rgba(249,115,22,0.3)] hover:-translate-y-0.5 transition-all duration-300 flex items-center gap-3 disabled:pointer-events-none"
                @click="handleNext"
              >
                <template v-if="isProcessing">
                  <motion.div
                    :animate="{ rotate: 360 }"
                    :transition="{ duration: 1, repeat: Infinity, ease: 'linear' }"
                    class="w-5 h-5 border-2 border-white/30 border-t-white rounded-full"
                  />
                  {{ ui.checkout.processingSubmitLabel }}
                </template>
                <template v-else>
                  {{ actionLabel }}
                  <ArrowLeft class="w-5 h-5 rotate-180" />
                </template>
              </button>
            </div>
          </div>
        </div>

        <div class="lg:col-span-5 xl:col-span-4">
          <CheckoutSummary :group="quoteGroup" :quote="quoteSummary" :offer="activeOffer" />
        </div>
      </div>
    </main>
  </div>
</template>
