<script setup>
import { AnimatePresence, motion } from 'motion-v'
import {
  ArrowRight,
  Calendar,
  ChevronDown,
  Clock,
  Gift,
  MapPin,
  Sparkles,
} from 'lucide-vue-next'
import { format } from 'date-fns'
import AppCalendar from '~/components/shared/AppCalendar.vue'
import HeroTimePopover from '~/components/home/hero/HeroTimePopover.vue'
import { buildRentExtrasRoute, buildRentSearchRoute, buildRentTripQuery } from '~/utils/public-routes'

const props = defineProps({
  offer: {
    type: Object,
    required: true,
  },
})

const formRef = ref(null)
const activePopover = ref(null)
const pickupLocation = ref(null)
const dropoffLocation = ref(null)
const returnToSameLocation = ref(true)
const pickupTime = ref('12:30')
const dropoffTime = ref('08:30')
const promoCode = ref('')
const isSubmitting = ref(false)
const validationError = ref('')
const { baseDay, buildDate } = usePublicDateDefaults()
const dateRange = ref({
  from: buildDate(0),
  to: buildDate(3),
})

const { locale } = usePublicLocale()
const { locations, loadLocations } = usePublicSiteLocations()
const ui = usePublicUi()

function resolveLocationByBackendId(id, fallbackIndex = 0) {
  const numericId = Number(id || 0)

  if (numericId > 0) {
    const matched = locations.value.find((item) => Number(item.backendId) === numericId)

    if (matched) {
      return matched
    }
  }

  return locations.value[fallbackIndex] || null
}

function toDateValue(value, fallbackDate) {
  if (!value) {
    return fallbackDate
  }

  const parsed = new Date(value)

  if (Number.isNaN(parsed.getTime())) {
    return fallbackDate
  }

  return parsed
}

function toTimeValue(value, fallbackTime) {
  if (!value) {
    return fallbackTime
  }

  const parsed = new Date(value)

  if (Number.isNaN(parsed.getTime())) {
    return fallbackTime
  }

  return format(parsed, 'HH:mm')
}

function buildIsoDateTime(dateValue, timeValue) {
  if (!(dateValue instanceof Date) || Number.isNaN(dateValue.getTime())) {
    return undefined
  }

  const [hours, minutes] = String(timeValue || '00:00').split(':').map((item) => Number(item))
  const nextDate = new Date(dateValue)
  nextDate.setHours(hours || 0, minutes || 0, 0, 0)
  return nextDate.toISOString()
}

function hydrateFromOffer() {
  if (!locations.value.length) {
    return
  }

  const prefill = props.offer?.bookingPrefill || {}
  const fallbackPickupDate = buildDate(0)
  const fallbackDropoffDate = buildDate(3)

  pickupLocation.value = resolveLocationByBackendId(prefill.pickupLocationId, 0)
  dropoffLocation.value = resolveLocationByBackendId(prefill.dropoffLocationId || prefill.pickupLocationId, 1) || pickupLocation.value
  returnToSameLocation.value = String(prefill.returnToSameLocation || '1') !== '0'
  pickupTime.value = toTimeValue(prefill.pickupAt, '12:30')
  dropoffTime.value = toTimeValue(prefill.dropoffAt, '08:30')
  promoCode.value = String(prefill.promoCode || '')
  dateRange.value = {
    from: toDateValue(prefill.pickupAt, fallbackPickupDate),
    to: toDateValue(prefill.dropoffAt, fallbackDropoffDate),
  }

  if (returnToSameLocation.value) {
    dropoffLocation.value = pickupLocation.value
  }
}

function togglePopover(name) {
  activePopover.value = activePopover.value === name ? null : name
}

function selectLocation(target, location) {
  if (target === 'pickup') {
    pickupLocation.value = location
  } else {
    dropoffLocation.value = location
  }

  activePopover.value = null
}

function handleClickOutside(event) {
  const formElement = formRef.value?.$el || formRef.value

  if (formElement && typeof formElement.contains === 'function' && !formElement.contains(event.target)) {
    activePopover.value = null
  }
}

const availableLocations = computed(() => locations.value || [])
const relatedVehicle = computed(() => props.offer?.relatedVehicle || null)
const prefillExtras = computed(() => props.offer?.bookingPrefill?.prefillExtras || [])
const prefillExtraLabels = computed(() => {
  return prefillExtras.value
    .map((entry) => String(entry || '').replaceAll('_', ' '))
    .filter(Boolean)
})
const effectiveDropoffLocation = computed(() => {
  return returnToSameLocation.value ? pickupLocation.value : dropoffLocation.value
})
const pickupLocationLabel = computed(() => pickupLocation.value?.name || ui.value.vehicles.pickup)
const dropoffLocationLabel = computed(() => effectiveDropoffLocation.value?.name || ui.value.vehicles.dropoff)
const dateRangeLabel = computed(() => {
  if (!dateRange.value?.from || !dateRange.value?.to) {
    return ui.value.vehicles.applyDates
  }

  return `${format(dateRange.value.from, 'MMM d')} - ${format(dateRange.value.to, 'MMM d')}`
})
const canSubmit = computed(() => {
  return Boolean(
    pickupLocation.value?.backendId
      && effectiveDropoffLocation.value?.backendId
      && dateRange.value?.from
      && dateRange.value?.to,
  )
})
const ctaLabel = computed(() => {
  return props.offer?.bookingPrefill?.vehicleGroupId ? ui.value.common.continue : ui.value.vehicles.browseCars
})
const helperText = computed(() => {
  return props.offer?.bookingPrefill?.vehicleGroupId
    ? ui.value.offers.includedFocusDescription
    : ui.value.offers.suggestedDatesDescription
})

watch(
  canSubmit,
  (value) => {
    if (value && validationError.value === ui.value.common.fillRequiredFields) {
      validationError.value = ''
    }
  },
)

watch(
  availableLocations,
  (value) => {
    if (value.length) {
      hydrateFromOffer()
    }
  },
  { immediate: true },
)

watch(
  () => returnToSameLocation.value,
  (value) => {
    if (value) {
      dropoffLocation.value = pickupLocation.value
      activePopover.value = activePopover.value === 'dropoff-location' ? null : activePopover.value
    }
  },
)

watch(
  () => pickupLocation.value,
  (value) => {
    if (returnToSameLocation.value) {
      dropoffLocation.value = value
    }
  },
)

onMounted(async () => {
  document.addEventListener('mousedown', handleClickOutside)
  await loadLocations()
})

onBeforeUnmount(() => {
  document.removeEventListener('mousedown', handleClickOutside)
})

async function continueToBooking() {
  if (!canSubmit.value || isSubmitting.value) {
    validationError.value = ui.value.common.fillRequiredFields
    return
  }

  isSubmitting.value = true
  validationError.value = ''

  try {
    const tripQuery = {
      ...buildRentTripQuery({
        pickupLocationId: pickupLocation.value?.backendId,
        dropoffLocationId: effectiveDropoffLocation.value?.backendId,
        pickupAt: buildIsoDateTime(dateRange.value.from, pickupTime.value),
        dropoffAt: buildIsoDateTime(dateRange.value.to, dropoffTime.value),
        promoCode: promoCode.value || undefined,
        prefillExtra: prefillExtras.value[0] || undefined,
        prefillExtras: prefillExtras.value.length > 1 ? prefillExtras.value.join(',') : undefined,
        returnToSameLocation: returnToSameLocation.value ? '1' : '0',
        driverAge: props.offer?.bookingPrefill?.driverAge || undefined,
        offerSlug: props.offer?.slug || undefined,
      }),
    }

    const targetRoute = props.offer?.bookingPrefill?.vehicleGroupId
      ? buildRentExtrasRoute(props.offer.bookingPrefill.vehicleGroupId, tripQuery, { locale: locale.value })
      : buildRentSearchRoute(tripQuery, { locale: locale.value })

    await navigateTo(targetRoute)
  } finally {
    isSubmitting.value = false
  }
}
</script>

<template>
  <div
    ref="formRef"
    class="rounded-[2.25rem] bg-white border border-slate-200 p-6 md:p-8 shadow-[0_18px_50px_-24px_rgba(15,23,42,0.18)]"
  >
    <div class="flex items-start justify-between gap-4 mb-6">
      <div>
        <div class="inline-flex items-center gap-2 px-3.5 py-2 rounded-full bg-slate-100 text-slate-500 text-[11px] font-bold tracking-[0.24em] uppercase mb-4">
          <Sparkles class="w-3.5 h-3.5 text-brand-orange" />
          {{ ui.offers.claimOffer }}
        </div>
        <h2 class="text-3xl md:text-[2rem] font-display font-black tracking-tight text-slate-900">{{ ui.offers.claimThisOffer }}</h2>
        <p class="text-slate-500 mt-2 leading-relaxed max-w-sm">
          {{ ui.offers.suggestedDatesDescription }}
        </p>
      </div>

      <div
        class="shrink-0 inline-flex items-center rounded-full bg-brand-orange px-4 py-2.5 text-sm font-black uppercase tracking-[0.08em] text-white shadow-[0_18px_36px_-18px_rgba(249,115,22,0.75)]"
      >
        {{ props.offer.discount || 'Offer' }}
      </div>
    </div>

    <div
      v-if="relatedVehicle"
      class="rounded-[2rem] border border-slate-200 bg-[linear-gradient(135deg,#fff7ed_0%,#ffffff_45%,#fffaf5_100%)] p-4 md:p-5 mb-4"
    >
      <div class="flex items-center gap-4">
        <img
          v-if="relatedVehicle.image"
          :src="relatedVehicle.image"
          :alt="relatedVehicle.name"
          class="w-24 h-24 rounded-[1.5rem] object-cover bg-white shadow-sm"
          referrerpolicy="no-referrer"
        >
        <div
          v-else
          class="flex h-24 w-24 shrink-0 items-center justify-center rounded-[1.5rem] bg-slate-100 border border-slate-200"
        >
          <div class="h-10 w-10 rounded-2xl bg-white shadow-sm border border-slate-200" />
        </div>
        <div class="min-w-0 flex-1">
          <div class="text-[11px] font-bold tracking-[0.24em] uppercase text-brand-orange mb-2">{{ ui.offers.offerVehicle }}</div>
          <div class="text-2xl font-display font-black tracking-tight text-slate-900 truncate">{{ relatedVehicle.name }}</div>
          <div class="text-slate-500 mt-1">{{ relatedVehicle.category || ui.offers.offerVehicleDescription }}</div>
        </div>
      </div>
    </div>

    <div v-if="prefillExtraLabels.length || promoCode" class="flex flex-wrap gap-2 mb-5">
      <span
        v-for="label in prefillExtraLabels"
        :key="label"
        class="inline-flex items-center rounded-full border border-brand-orange/20 bg-brand-orange/10 px-3 py-1.5 text-[11px] font-bold uppercase tracking-[0.18em] text-brand-orange"
      >
        {{ label }}
      </span>
      <span
        v-if="promoCode"
        class="inline-flex items-center rounded-full border border-slate-200 bg-slate-100 px-3 py-1.5 text-[11px] font-bold uppercase tracking-[0.18em] text-slate-600"
      >
        {{ ui.offers.promoCode }} {{ promoCode }}
      </span>
    </div>

    <div class="grid grid-cols-1 gap-3 mb-3">
      <div class="relative">
        <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">{{ ui.extras.pickup }}</div>
        <button
          type="button"
          class="w-full flex items-center justify-between gap-3 px-4 py-4 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-[1.5rem] transition-all group text-left"
          @click="togglePopover('pickup-location')"
        >
          <div class="flex items-center gap-3 min-w-0">
            <div class="w-10 h-10 rounded-full bg-white shadow-sm flex items-center justify-center">
              <MapPin class="w-4.5 h-4.5 text-slate-600 group-hover:text-brand-orange" />
            </div>
            <div class="min-w-0">
              <div class="font-bold text-slate-900 text-lg truncate">{{ pickupLocationLabel }}</div>
              <div v-if="pickupLocation?.city" class="text-xs text-slate-500 mt-0.5 truncate">{{ pickupLocation.city }}</div>
            </div>
          </div>
          <ChevronDown class="w-4 h-4 text-slate-400 shrink-0" />
        </button>

        <AnimatePresence>
          <motion.div
            v-if="activePopover === 'pickup-location'"
            :initial="{ opacity: 0, y: 10, scale: 0.96 }"
            :animate="{ opacity: 1, y: 0, scale: 1 }"
            :exit="{ opacity: 0, y: 10, scale: 0.96 }"
            :transition="{ duration: 0.2 }"
            class="absolute top-full left-0 right-0 mt-2 bg-white rounded-[1.5rem] shadow-[0_24px_60px_-24px_rgba(15,23,42,0.2)] border border-slate-100 p-2 z-50"
          >
            <button
              v-for="location in availableLocations"
              :key="`pickup-${location.id}`"
              type="button"
              :class="[
                'w-full text-left px-4 py-3 rounded-xl transition-all duration-200',
                pickupLocation?.id === location.id
                  ? 'bg-brand-orange/10 text-brand-orange'
                  : 'text-slate-700 hover:bg-slate-50',
              ]"
              @click="selectLocation('pickup', location)"
            >
              <div class="font-bold text-sm">{{ location.name }}</div>
              <div class="text-[11px] text-slate-500 mt-0.5">{{ location.city || location.code }}</div>
            </button>
          </motion.div>
        </AnimatePresence>
      </div>

      <label class="flex items-center justify-between px-4 py-4 bg-slate-50 border border-slate-200 rounded-[1.5rem]">
        <div>
          <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1">{{ ui.extras.dropoff }}</div>
          <div class="font-semibold text-slate-700 text-sm">{{ ui.offers.returnToSameLocation }}</div>
        </div>
        <button
          type="button"
          class="relative"
          @click="returnToSameLocation = !returnToSameLocation"
        >
          <div :class="['relative w-11 h-6 rounded-full transition-colors duration-300', returnToSameLocation ? 'bg-brand-orange' : 'bg-slate-200']">
            <motion.div
              class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow-md"
              :animate="{ x: returnToSameLocation ? 20 : 0 }"
              :transition="{ type: 'spring', stiffness: 420, damping: 30 }"
            />
          </div>
        </button>
      </label>

      <div class="relative">
        <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">{{ ui.extras.dropoff }}</div>
        <button
          type="button"
          :disabled="returnToSameLocation"
          :class="[
            'w-full flex items-center justify-between gap-3 px-4 py-4 border rounded-[1.5rem] transition-all text-left',
            returnToSameLocation
              ? 'bg-slate-50 border-slate-200 text-slate-400 cursor-default'
              : 'bg-slate-50 hover:bg-slate-100 border-slate-200 group',
          ]"
          @click="!returnToSameLocation && togglePopover('dropoff-location')"
        >
          <div class="flex items-center gap-3 min-w-0">
            <div class="w-10 h-10 rounded-full bg-white shadow-sm flex items-center justify-center">
              <MapPin class="w-4.5 h-4.5" :class="returnToSameLocation ? 'text-slate-300' : 'text-slate-600 group-hover:text-brand-orange'" />
            </div>
            <div class="min-w-0">
              <div class="font-bold text-slate-900 text-lg truncate">{{ dropoffLocationLabel }}</div>
              <div class="text-xs mt-0.5 truncate" :class="returnToSameLocation ? 'text-slate-400' : 'text-slate-500'">
                {{ returnToSameLocation ? ui.offers.returnToSameLocation : (effectiveDropoffLocation?.city || effectiveDropoffLocation?.code || '') }}
              </div>
            </div>
          </div>
          <ChevronDown v-if="!returnToSameLocation" class="w-4 h-4 text-slate-400 shrink-0" />
        </button>

        <AnimatePresence>
          <motion.div
            v-if="activePopover === 'dropoff-location' && !returnToSameLocation"
            :initial="{ opacity: 0, y: 10, scale: 0.96 }"
            :animate="{ opacity: 1, y: 0, scale: 1 }"
            :exit="{ opacity: 0, y: 10, scale: 0.96 }"
            :transition="{ duration: 0.2 }"
            class="absolute top-full left-0 right-0 mt-2 bg-white rounded-[1.5rem] shadow-[0_24px_60px_-24px_rgba(15,23,42,0.2)] border border-slate-100 p-2 z-50"
          >
            <button
              v-for="location in availableLocations"
              :key="`dropoff-${location.id}`"
              type="button"
              :class="[
                'w-full text-left px-4 py-3 rounded-xl transition-all duration-200',
                effectiveDropoffLocation?.id === location.id
                  ? 'bg-brand-orange/10 text-brand-orange'
                  : 'text-slate-700 hover:bg-slate-50',
              ]"
              @click="selectLocation('dropoff', location)"
            >
              <div class="font-bold text-sm">{{ location.name }}</div>
              <div class="text-[11px] text-slate-500 mt-0.5">{{ location.city || location.code }}</div>
            </button>
          </motion.div>
        </AnimatePresence>
      </div>
    </div>

    <div class="relative mb-3 z-20">
      <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">{{ ui.offers.rentalPeriod }}</div>
      <button
        type="button"
        class="w-full flex items-center justify-between px-4 py-4 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-[1.5rem] transition-all group"
        @click="togglePopover('dates')"
      >
        <div class="flex items-center gap-3">
          <div class="w-10 h-10 rounded-full bg-white shadow-sm flex items-center justify-center">
            <Calendar class="w-4.5 h-4.5 text-slate-600 group-hover:text-brand-orange" />
          </div>
          <div class="text-left">
            <div class="font-bold text-slate-900 text-lg">
              {{ dateRangeLabel }}
            </div>
            <div class="text-xs text-slate-500 mt-0.5">
              {{ ui.offers.suggestedDatesDescription }}
            </div>
          </div>
        </div>
        <ChevronDown class="w-4 h-4 text-slate-400" />
      </button>

      <AnimatePresence>
        <motion.div
          v-if="activePopover === 'dates'"
          :initial="{ opacity: 0, y: 10, scale: 0.96 }"
          :animate="{ opacity: 1, y: 0, scale: 1 }"
          :exit="{ opacity: 0, y: 10, scale: 0.96 }"
          :transition="{ duration: 0.2 }"
          class="absolute top-full left-0 md:left-1/2 md:-translate-x-1/2 mt-2 bg-white border border-slate-100 rounded-[1.75rem] shadow-[0_24px_60px_-24px_rgba(15,23,42,0.2)] p-4 z-50 w-max max-w-[calc(100vw-2rem)]"
        >
          <AppCalendar
            mode="range"
            :selected="dateRange"
            :number-of-months="1"
            :disabled="{ before: baseDay }"
            class="font-sans flex justify-center"
            @select="dateRange = $event"
          />
          <div class="mt-4 pt-4 border-t border-slate-200/60 flex justify-end">
            <button
              type="button"
              class="px-5 py-2.5 bg-slate-900 text-white rounded-xl text-sm font-bold hover:bg-brand-orange transition-colors"
              @click="activePopover = null"
            >
              {{ ui.vehicles.applyDates }}
            </button>
          </div>
        </motion.div>
      </AnimatePresence>
    </div>

    <div class="grid grid-cols-2 gap-3 mb-3">
      <div class="relative">
        <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">{{ ui.offers.pickupTime }}</div>
        <button
          type="button"
          class="w-full flex items-center justify-between gap-3 px-4 py-4 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-[1.5rem] transition-all group"
          @click="togglePopover('pickup-time')"
        >
          <div class="flex items-center gap-3">
            <div class="w-10 h-10 rounded-full bg-white shadow-sm flex items-center justify-center">
              <Clock class="w-4.5 h-4.5 text-slate-600 group-hover:text-brand-orange" />
            </div>
            <div class="font-bold text-slate-900 text-lg">{{ pickupTime }}</div>
          </div>
          <ChevronDown class="w-4 h-4 text-slate-400 shrink-0" />
        </button>

        <AnimatePresence>
          <HeroTimePopover
            v-if="activePopover === 'pickup-time'"
            :selected-time="pickupTime"
            @select="(time) => { pickupTime = time; activePopover = null }"
          />
        </AnimatePresence>
      </div>

      <div class="relative">
        <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">{{ ui.offers.dropoffTime }}</div>
        <button
          type="button"
          class="w-full flex items-center justify-between gap-3 px-4 py-4 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-[1.5rem] transition-all group"
          @click="togglePopover('dropoff-time')"
        >
          <div class="flex items-center gap-3">
            <div class="w-10 h-10 rounded-full bg-white shadow-sm flex items-center justify-center">
              <Clock class="w-4.5 h-4.5 text-slate-600 group-hover:text-brand-orange" />
            </div>
            <div class="font-bold text-slate-900 text-lg">{{ dropoffTime }}</div>
          </div>
          <ChevronDown class="w-4 h-4 text-slate-400 shrink-0" />
        </button>

        <AnimatePresence>
          <HeroTimePopover
            v-if="activePopover === 'dropoff-time'"
            :selected-time="dropoffTime"
            align="right"
            @select="(time) => { dropoffTime = time; activePopover = null }"
          />
        </AnimatePresence>
      </div>
    </div>

    <label class="block mb-6">
      <div class="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2">{{ ui.offers.promoCode }}</div>
      <div class="flex items-center gap-3 px-4 py-4 bg-slate-50 border border-slate-200 rounded-[1.5rem]">
        <div class="w-10 h-10 rounded-full bg-white shadow-sm flex items-center justify-center">
          <Gift class="w-4.5 h-4.5 text-brand-orange" />
        </div>
        <input
          v-model="promoCode"
          type="text"
          class="w-full bg-transparent text-slate-900 text-lg font-semibold outline-none placeholder:text-slate-300"
          :placeholder="ui.offers.promoCode"
        >
      </div>
    </label>

    <button
      type="button"
      :disabled="isSubmitting"
      class="w-full inline-flex items-center justify-center gap-3 rounded-full bg-brand-orange text-white px-6 py-4 font-bold uppercase tracking-[0.22em] transition-all duration-300 shadow-[0_22px_42px_-18px_rgba(249,115,22,0.65)] disabled:opacity-100 disabled:bg-brand-orange disabled:text-white"
      @click="continueToBooking"
    >
      <div v-if="isSubmitting" class="w-5 h-5 border-2 border-white/40 border-t-white rounded-full animate-spin" />
      <span>{{ isSubmitting ? ui.common.sendingRequest : ctaLabel }}</span>
      <ArrowRight class="w-5 h-5" />
    </button>

    <p class="text-sm text-slate-500 leading-relaxed mt-4">
      {{ helperText }}
    </p>

    <p v-if="validationError" class="mt-4 rounded-2xl border border-red-100 bg-red-50/80 px-4 py-3 text-sm text-red-600">
      {{ validationError }}
    </p>
  </div>
</template>
