<template>
	<main class="pt-4 lg:container mx-auto px-4 pb-20">
		<!-- Error state -->
		<div v-if="displayState === 'error'" class="py-12">
			<CheckoutError @retry="cart.retry()" />
		</div>

		<!-- Loading skeleton -->
		<div v-else-if="displayState === 'loading'">
			<Stepper :step="2" />
			<div class="mt-8 mb-12 max-w-screen-md mx-auto">
				<div class="h-8 w-3/4 bg-gray-200 rounded mb-8 animate-pulse"></div>
				<CheckoutSkeleton variant="form" :fields="4" />
				<hr class="my-12" />
				<CheckoutSkeleton variant="delivery" />
				<hr class="my-12" />
				<div class="h-12 bg-gray-200 rounded-full w-full animate-pulse"></div>
			</div>
		</div>

		<!-- Terms warning -->
		<div v-else-if="displayState === 'terms-warning'">
			<div class="bg-yellow-100 border-l-4 border-yellow-500 p-4 mb-8">
				<p class="text-yellow-700 font-semibold mb-4">
					Bitte, akzeptiere die
					<a href="/agb" target="_blank" class="underline" @click="trackEvent('checkout-terms-clicked')">AGB</a>
					und
					<a href="/datenschutz" target="_blank" class="underline" @click="trackEvent('checkout-privacy-clicked')">Datenschutzerklärung</a>, um fortzufahren.
				</p>
				<NuxtLink to="/checkout/1" class="text-yellow-700 hover:underline">Zurück zur Kasse</NuxtLink>
			</div>
		</div>

		<!-- Main content -->
		<div v-else-if="displayState === 'main-content'">
			<Stepper :step="2" />

			<div class="mt-8 mb-12 flex flex-col gap-8 max-w-screen-md mx-auto">
				<Heading html-tag="h1" :level="2">Gib deinen Namen und Adresse ein:</Heading>

				<form @submit.prevent="submit" v-if="uuid">
					<div class="flex flex-col gap-4 max-w-screen-md">
						<Input label="Vorname" v-model="address.name" :required="true" autocomplete="given-name" />
						<Input label="Nachname" v-model="address.surname" :required="true" autocomplete="family-name" />
						<Input label="Straße und Hausnummer:" v-model="address.street" :required="true" autocomplete="street-address" />
						<div class="flex gap-4">
							<Input label="PLZ" v-model="address.postalCode" :required="true" label-class="w-1/2" autocomplete="postal-code" />
							<Input label="Ort" v-model="address.city" :required="true" label-class="w-1/2" autocomplete="address-level2" />
						</div>

						<label class="flex items-center gap-2 my-4 cursor-pointer">
							<input type="checkbox" v-model="showOptionalDeliveryAddress" />
							<span>Abweichende Lieferadresse</span>
						</label>
					</div>

					<div class="flex flex-col gap-4 max-w-screen-md" v-if="showOptionalDeliveryAddress">
						<Input label="Vorname" v-model="deliveryAddress.name" :required="showOptionalDeliveryAddress" />
						<Input label="Nachname" v-model="deliveryAddress.surname" :required="showOptionalDeliveryAddress" />
						<Input label="Straße und Hausnummer:" v-model="deliveryAddress.street" :required="showOptionalDeliveryAddress" />
						<div class="flex gap-4">
							<Input label="PLZ" v-model="deliveryAddress.postalCode" label-class="w-1/2" :required="showOptionalDeliveryAddress" />
							<Input label="Ort" v-model="deliveryAddress.city" label-class="w-1/2" :required="showOptionalDeliveryAddress" />
						</div>
					</div>

					<hr class="my-12" />

					<fieldset class="space-y-4 mb-8" aria-required="true">
						<p class="text-md font-semibold">Wähle deine Versandart:</p>
						<div v-for="method in deliveryMethods" :key="method.id" class="relative">
							<input
								type="radio"
								name="delivery-method"
								:id="'delivery-' + method.id"
								:value="method.id"
								v-model="selectedDeliveryMethod"
								class="peer right-6 top-6 absolute"
								required
							/>
							<label
								:for="'delivery-' + method.id"
								class="inline-flex items-center justify-between w-full p-5 bg-white border-2 rounded-lg cursor-pointer group border-neutral-200/70 text-neutral-600 peer-checked:border-blue-400 peer-checked:text-neutral-900 peer-checked:bg-blue-200/50 hover:text-neutral-900 hover:border-neutral-300"
							>
								<div class="flex items-center space-x-5">
									<div class="flex flex-col justify-start">
										<div class="w-full text-lg font-semibold">{{ method.name }}</div>
										<div class="w-full text-sm opacity-60">{{ method.description }}</div>
										<div class="w-full text-sm mt-2 font-medium">
											{{ method.price === 0 ? "Kostenlos" : numberFormatter(method.price, "€") }}
										</div>
									</div>
								</div>
							</label>
						</div>
					</fieldset>

					<hr class="my-12" />

					<div class="mt-12">
						<Button classes="w-full" type="submit" :is-pending="formSubmitIsPending">Weiter zur Zahlung</Button>
					</div>
				</form>
			</div>
		</div>
	</main>
</template>

<script setup lang="ts">
import type { Address, StructuredAddress } from "~/types";
import { trackEvent } from "~/utils/trackEvent";
import { numberFormatter } from "~/utils/numberFormatter";

const cart = useCart();
const shopApi = useShopApi();

const isLoading = ref(true);

const displayState = computed(() => {
	// Error state - show retry option
	if (cart.hasError.value) {
		return "error";
	}
	// Still loading
	if (isLoading.value) {
		return "loading";
	}
	// Terms not accepted - show warning
	if (!acceptedTermsAndConditionsAt.value) {
		return "terms-warning";
	}
	// Ready to show form
	return "main-content";
});
const showOptionalDeliveryAddress = ref(false);
const formSubmitIsPending = ref(false);
const deliveryMethods = ref<any[]>([]);
const selectedDeliveryMethod = ref<number | null>(null);

const address = ref<Address>({
	name: "",
	surname: "",
	street: "",
	postalCode: "",
	city: ""
});

const deliveryAddress = ref<Address>({
	name: "",
	surname: "",
	street: "",
	postalCode: "",
	city: ""
});

const uuid = computed(() => cart.uuid.value);
const acceptedTermsAndConditionsAt = computed(() => cart.acceptedTermsAndConditionsAt.value);

onMounted(async () => {
	try {
		// Ensure cart is initialized first
		await cart.ensureReady();

		const { data } = await shopApi.getDeliveryMethods();
		deliveryMethods.value = data.map(({ id, attributes }: any) => ({ id, ...attributes }));
		selectedDeliveryMethod.value = cart.deliveryMethod.value;

		if (cart.invoiceAddressStructured.value) {
			address.value = {
				name: cart.invoiceAddressStructured.value.givenName,
				surname: cart.invoiceAddressStructured.value.familyName,
				street: cart.invoiceAddressStructured.value.streetAddress,
				city: cart.invoiceAddressStructured.value.addressLevel2,
				postalCode: cart.invoiceAddressStructured.value.postalCode
			};
		}

		if (cart.deliveryAddressStructured.value) {
			deliveryAddress.value = {
				name: cart.deliveryAddressStructured.value.givenName,
				surname: cart.deliveryAddressStructured.value.familyName,
				street: cart.deliveryAddressStructured.value.streetAddress,
				city: cart.deliveryAddressStructured.value.addressLevel2,
				postalCode: cart.deliveryAddressStructured.value.postalCode
			};
		}
	// Track checkout step 2 view
		trackEvent("checkout-step-2-viewed", {
			cartValue: cart.total.value
		});
	} catch (e) {
		console.error("Error fetching delivery methods", e);
	} finally {
		isLoading.value = false;
	}
});

// Track delivery method selection
watch(selectedDeliveryMethod, (methodId) => {
	if (methodId) {
		const method = deliveryMethods.value.find((m) => m.id === methodId);
		trackEvent("checkout-step-2-delivery-selected", {
			methodId,
			methodName: method?.name,
			price: method?.price ?? 0
		});
	}
});

// Track different delivery address toggle
watch(showOptionalDeliveryAddress, (toggled) => {
	if (toggled) {
		trackEvent("checkout-step-2-different-delivery-toggled");
	}
});

function mapToStructuredAddress(addr: Address): StructuredAddress {
	return {
		givenName: addr.name,
		familyName: addr.surname,
		streetAddress: addr.street,
		postalCode: addr.postalCode,
		addressLevel2: addr.city,
		country: "DE"
	};
}

function addressToString(addr: Address) {
	return `${addr.name} ${addr.surname}\n${addr.street}\n${addr.postalCode} ${addr.city}`;
}

async function submit() {
	if (!uuid.value) {
		console.error("Cart not found, cannot submit address form");
		return;
	}

	const invoiceAddressString = addressToString(address.value);
	const deliveryAddressString = showOptionalDeliveryAddress.value ? addressToString(deliveryAddress.value) : invoiceAddressString;

	const invoiceAddressStructured = mapToStructuredAddress(address.value);
	const deliveryAddressStructured = showOptionalDeliveryAddress.value ? mapToStructuredAddress(deliveryAddress.value) : invoiceAddressStructured;

	try {
		formSubmitIsPending.value = true;

		// Use cart.update() to sync local state after API call
		await cart.update({
			invoiceAddress: invoiceAddressString,
			deliveryAddress: deliveryAddressString,
			invoiceAddressStructured,
			deliveryAddressStructured,
			delivery: selectedDeliveryMethod.value
		});

		const selectedMethod = deliveryMethods.value.find((m) => m.id === selectedDeliveryMethod.value);
		trackEvent("checkout-step-2-completed", {
			cartValue: cart.total.value,
			deliveryMethod: selectedMethod?.name
		});

		navigateTo("/checkout/3");
	} catch (error) {
		console.error("Error submitting address form:", error);
	} finally {
		formSubmitIsPending.value = false;
	}
}

// SEO
useSeoMeta({
	title: "Checkout - Adresse | MUELLERPRINTS"
});
</script>
