<template>
	<div v-if="displayState === 'loading'" class="pt-0">
		<div class="flex items-center justify-center h-[60vh] mt-24">
			<div class="text-center">
				<LoadingSpinner />
				<p class="text-2xl mt-8 font-semibold">Produktbeschreibung wird geladen...</p>
			</div>
		</div>
	</div>

	<div v-else-if="displayState === 'not-found-error'" class="pt-0">
		<div class="flex items-center justify-center h-[60vh] mt-24">
			<div class="text-center">
				<div class="w-12 h-12"></div>
				<p class="text-2xl mt-8 font-semibold">Produkt nicht gefunden</p>
				<p class="text-lg mt-6">
					Vielleicht ist das Produkt aktuell nicht lieferbar. Falls du Auskunft erhalten möchtest,
					<a href="/kontakt" class="underline">kontaktiere uns</a> und schicke diese Produkt-Nr. mit:
				</p>
				<pre class="mt-3 p-2 rounded-sm bg-gray-100">Produkt-Nr.: {{ slug }}</pre>
			</div>
		</div>
	</div>

	<Background
		v-else-if="displayState === 'main-content'"
		:coverId="product?.cover?.id"
		:patternId="product?.pattern?.id"
		:shade="200"
		class="pt-0"
		itemscope
		:gradient="true"
		itemtype="https://schema.org/Product"
	>
		<!-- Schema.org metadata -->
		<meta itemprop="name" :content="product?.name" />
		<meta itemprop="description" :content="getProductDescription()" />
		<meta itemprop="image" :content="productImage?.url" />
		<meta itemprop="sku" :content="String(product?.id)" />
		<div itemprop="brand" itemscope itemtype="https://schema.org/Brand">
			<meta itemprop="name" content="MUELLERPRINTS. Paperwork" />
			<meta itemprop="image" content="https://muellerprints-paperwork.com/paperwork-logo.png" />
		</div>

		<!-- Aggregate Rating -->
		<div v-if="aggregateRating" itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
			<meta itemprop="ratingValue" :content="aggregateRating.ratingValue" />
			<meta itemprop="ratingCount" :content="aggregateRating.ratingCount" />
			<meta itemprop="reviewCount" :content="aggregateRating.reviewCount" />
			<meta itemprop="bestRating" content="5" />
			<meta itemprop="worstRating" content="1" />
		</div>

		<!-- Reviews -->
		<div v-for="(testimonial, index) in testimonials" :key="index" itemprop="review" itemscope itemtype="https://schema.org/Review">
			<div itemprop="reviewRating" itemscope itemtype="https://schema.org/Rating">
				<meta itemprop="ratingValue" :content="String(testimonial.rating)" />
				<meta itemprop="worstRating" content="1" />
				<meta itemprop="bestRating" content="5" />
			</div>
			<div itemprop="author" itemscope itemtype="https://schema.org/Person">
				<meta itemprop="name" :content="testimonial.name ?? 'Unknown'" />
			</div>
			<meta itemprop="reviewBody" :content="testimonial.comment" />
		</div>

		<main class="pt-10 px-6 xl:container lg:mx-auto">
			<div>
				<p class="text-gray-800 text-lg">{{ product?.cover?.copyText?.format }}</p>
				<Heading :level="1" html-tag="h1" classes="xl:w-2/3">
					<span data-e2e="title">{{ product?.name }}</span>
				</Heading>
				<Heading :level="2" html-tag="h2" classes="xl:w-2/3">
					<span data-e2e="subtitle" v-html="product?.cover?.copyText?.details"></span>
				</Heading>
				<p class="text-gray-800 text-lg lg:w-4/5" data-e2e="subtitle">
					{{ product?.cover?.copyText?.paper }}
				</p>

				<div class="flex flex-col-reverse lg:flex-row-reverse gap-4 xl:gap-12">
					<div class="lg:w-1/2 xl:w-2/5 xl:pt-8">
						<div class="rounded-lg bg-white bg-opacity-100 shadow-md mb-16 relative">
							<!-- Pages Variant Selection -->
							<section
								v-if="productVariantsPages?.length"
								class="relative overflow-hidden flex flex-col xl:flex-row-reverse gap-4 xl:gap-12 py-6 px-6 xl:px-8 xl:pt-20"
							>
								<h2 class="hidden lg:block pointer-events-none absolute left-8 top-4 text-right xl:text-left pt-3 tracking-tight opacity-70 text-xl font-semibold">
									Seiten
								</h2>
								<div class="flex gap-4 z-10">
									<SelectionBox
										v-for="pages in productVariantsPages"
										:key="pages.id"
										:label="pages.name"
										:path="pages.productSlug ? `/details/${pages.productSlug}` : ''"
										:is-active="pages.active"
										:aria-disabled="isAddingToCart || isChangingVariant"
										@click="handleVariantClick('pages', pages)"
									/>
								</div>
							</section>
							<hr v-if="productVariantsPages?.length" class="border-t-[1px] border-black opacity-40" />

							<!-- Ruling Variant Selection -->
							<section
								v-if="productVariantsRuling?.length"
								class="relative overflow-hidden flex flex-col xl:flex-row-reverse gap-4 xl:gap-12 py-6 px-6 xl:px-8 xl:pt-20"
							>
								<h2 class="hidden lg:block pointer-events-none absolute left-8 top-4 text-right xl:text-left pt-3 tracking-tight opacity-70 text-xl font-semibold">
									Layout
								</h2>
								<div class="flex gap-4 z-10">
									<SelectionBox
										v-for="ruling in productVariantsRuling"
										:key="ruling.id"
										:label="ruling.name"
										:path="ruling.productSlug ? `/details/${ruling.productSlug}` : ''"
										:is-active="ruling.active"
										:aria-disabled="isAddingToCart || isChangingVariant"
										@click="handleVariantClick('ruling', ruling)"
									>
										<img v-if="ruling.iconUrl" :alt="ruling.name" :src="ruling.iconUrl" />
									</SelectionBox>
								</div>
							</section>
							<hr v-if="productVariantsRuling?.length" class="border-t-[1px] border-black opacity-40" />

							<!-- Cover Variant Selection -->
							<section
								v-if="productVariantsCover?.length"
								class="flex flex-col relative xl:flex-row-reverse gap-4 xl:gap-12 py-6 px-6 xl:px-8 xl:pt-20 overflow-hidden"
							>
								<h2 class="hidden lg:block pointer-events-none absolute left-8 top-4 text-right xl:text-left pt-3 tracking-tight opacity-70 text-xl font-semibold">
									Einband
								</h2>
								<div class="flex gap-4 z-10">
									<SelectionBox
										v-for="cover in productVariantsCover"
										:key="cover.id"
										:label="cover.name"
										:path="cover.productSlug ? `/details/${cover.productSlug}` : ''"
										:is-active="cover.active"
										:aria-disabled="isAddingToCart || isChangingVariant"
										@click="handleVariantClick('cover', cover)"
									>
										<img v-if="cover.iconUrl" :alt="cover.name" :src="cover.iconUrl" />
									</SelectionBox>
								</div>
							</section>
							<hr v-if="productVariantsCover?.length" class="border-t-[1px] border-black opacity-40" />

							<!-- Price and Add to Cart -->
							<section v-if="product?.totalProductPrice" class="flex flex-col lg:flex-row gap-6 py-6 px-6 lg:px-8 items-center">
								<div class="w-full lg:w-1/3 flex flex-row-reverse lg:flex-row" itemprop="offers" itemscope itemtype="http://schema.org/Offer">
									<meta itemprop="priceCurrency" content="EUR" />
									<meta itemprop="price" :content="formatPriceForSchema(product.totalProductPrice)" />
									<meta itemprop="priceValidUntil" :content="getPriceValidUntilDate()" />
									<meta itemprop="availability" content="https://schema.org/InStock" />
									<meta itemprop="url" :content="getProductUrl()" />
									<meta itemprop="itemCondition" content="https://schema.org/NewCondition" />
									<span class="oldstyle-nums text-3xl tracking-tight font-bold text-nowrap">
										{{ numberFormatter(product.totalProductPrice) }} €
									</span>
								</div>
								<div class="w-full lg:w-2/3">
									<Button @click="addToCart" :is-pending="isAddingToCart" classes="w-full">In den Warenkorb</Button>
								</div>
							</section>
							<section v-else class="py-6 px-6 lg:px-8">
								<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
									<meta itemprop="availability" content="https://schema.org/OutOfStock" />
									<meta itemprop="url" :content="getProductUrl()" />
									<meta itemprop="itemCondition" content="https://schema.org/NewCondition" />
								</div>
								<Button :classes="`w-full ${ctaBgColor}`">Produktanfrage</Button>
								<p class="text-xs p-4 px-6 text-gray-600">
									Aktuell können wir diesen Artikel nicht liefern. Schicke uns bitte eine Anfrage, dann erfährst du als Erstes sobald wir wieder lieferfähig sind. Danke für deine Geduld!
								</p>
							</section>
						</div>

						<div class="flex flex-col my-4 items-center gap-4">
							<img class="h-10" src="~/assets/visa-mastercard-paypal.svg" alt="VISA Mastercard PayPal Logos" />
							<span class="text-sm text-center w-4/5 opacity-60">Unterstützte Zahlungsanbieter: VISA, Mastercard und PayPal mit SSL Verschlüsselung</span>
						</div>
					</div>

					<div class="flex flex-col items-center lg:w-1/2 xl:w-3/5 xl:pt-2 mx-auto">
						<a v-if="productImage" :href="productImage.url" class="flex items-center justify-center mx-8" target="_blank" rel="noopener noreferrer">
							<img :src="productImage.formats?.medium?.url" :alt="`Overhead product shot of MUELLERPRINTS. Paperwork ${product?.name}`" class="object-contain" />
						</a>
						<div v-else class="bg-black opacity-5 shadow-sm w-full object-cover min-h-48"></div>
					</div>
				</div>
			</div>
		</main>
	</Background>

	<!-- Trust Bar -->
	<TrustBar v-if="displayState === 'main-content'" variant="light" />

	<!-- Feature Modules -->
	<template v-if="displayState === 'main-content' && featureModules.length">
		<FeatureModule
			v-for="(module, i) in featureModules"
			:key="i"
			:id="`feature-${i}`"
			:eyebrow="module.eyebrow"
			:headline="module.headline"
			:subtitle="module.subtitle"
			:body="module.body"
			:image="module.image"
			:image-right="module.imageRight"
			:class="i % 2 === 0 ? 'bg-white' : 'bg-gray-50'"
		/>
	</template>

	<!-- Technical Specs -->
	<TechnicalSpecs v-if="displayState === 'main-content'" :specs="technicalSpecs" />

	<!-- Use Case Grid -->
	<UseCaseGrid v-if="displayState === 'main-content'" :use-cases="useCases" />

	<!-- Pattern Variants Section -->
	<section
		class="py-16 xl:container mx-auto px-6"
		v-if="displayState === 'main-content' && productVariantsPatterns?.length"
		data-e2e="pattern-variants"
	>
		<div class="text-center mb-10">
			<h3 class="text-2xl font-bold mb-3">{{ productVariantsPatterns.length }} weitere Muster</h3>
			<p class="text-gray-600 max-w-2xl mx-auto">
				Jedes Muster ist ein Unikat. Finde das Design, das zu dir passt.
			</p>
		</div>

		<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-6 lg:gap-8">
			<div v-for="pattern in productVariantsPatterns" :key="pattern.id">
				<ProductCard :product="pattern.product" variant="neutral" />
			</div>
		</div>
	</section>

	<!-- Testimonials Section (hidden for now)
	<section v-if="displayState === 'main-content' && testimonials.length > 0" class="py-16 px-6 xl:container mx-auto">
		<div class="text-center mb-10">
			<h3 class="text-2xl font-bold mb-3">Kundenstimmen</h3>
			<p class="text-gray-600 max-w-2xl mx-auto">Was unsere Kunden über ihre Notizbücher sagen.</p>
		</div>
		<LazyTestimonial
			:testimonials="testimonials"
			:show-title="false"
			:show-rating="true"
			:show-avatar="false"
			:show-quote-icon="true"
			primary-color="#374151"
			star-color="#374151"
		/>
	</section>
	-->
</template>

<script setup lang="ts">
import { numberFormatter } from "~/utils/numberFormatter";
import { randomTailwindColor } from "~/utils/randomTailwindColor";
import { trackEvent } from "~/utils/trackEvent";
import { scrollProgress } from "~/utils/scrollProgress";
import { useProductContent } from "~/composables/useProductContent";
import type { Product, ProductVariantResponse, PatternVariantsResponse, Testimonial } from "~/types";

const route = useRoute();
const slug = computed(() => route.params.slug as string);

const shopApi = useShopApi();
const { addProduct: cartAddProduct } = useCart();

const isAddingToCart = ref(false);
const isChangingVariant = ref(false);
const hasScrolled50 = ref(false);
const hasScrolled100 = ref(false);

// Fetch all product data in one useAsyncData call for reliable SSR
const { data: pageData, status, refresh } = await useAsyncData(
	() => `product-page-${slug.value}`,
	async () => {
		// First fetch the product
		const product = await $fetch<Product | null>(`/api/product/${slug.value}`);

		if (!product?.id) {
			return { product: null, productVariants: { pages: [], ruling: [], cover: [] }, patternVariants: { patterns: [] } };
		}

		// Then fetch variants in parallel
		const [productVariants, patternVariants] = await Promise.all([
			$fetch<ProductVariantResponse>(`/api/products/${product.id}/variants`).catch(() => ({ pages: [], ruling: [], cover: [] })),
			$fetch<PatternVariantsResponse>(`/api/products/${product.id}/variants/pattern`).catch(() => ({ patterns: [] }))
		]);

		return { product, productVariants, patternVariants };
	},
	{
		default: () => ({
			product: null as Product | null,
			productVariants: { pages: [], ruling: [], cover: [] } as ProductVariantResponse,
			patternVariants: { patterns: [] } as PatternVariantsResponse
		})
	}
);

// Refetch when slug changes (client-side navigation)
watch(slug, async () => {
	await refresh();
	isChangingVariant.value = false;
});

const product = computed(() => pageData.value?.product ?? null);
const productVariants = computed(() => pageData.value?.productVariants ?? { pages: [], ruling: [], cover: [] });
const patternVariants = computed(() => pageData.value?.patternVariants ?? { patterns: [] });

// Product content for storytelling modules
const coverName = computed(() => product.value?.cover?.name);
const { coverType, featureModules: baseFeatureModules, technicalSpecs, useCases } = useProductContent(coverName, product);

// Merge feature modules with slide images from CMS
const featureModules = computed(() => {
	const slides = product.value?.cover?.slides ?? [];
	return baseFeatureModules.value.map((module, i) => ({
		...module,
		image: slides[i]?.url ?? module.image,
	}));
});

const displayState = computed(() => {
	// Show loading only on initial load (no data yet)
	if (status.value === "pending" && !product.value?.id) return "loading";
	// Keep showing current content while refreshing
	if (product.value?.id && product.value.publishedAt) return "main-content";
	// Only show error if we're not loading and have no product
	if (status.value !== "pending" && !product.value?.id) return "not-found-error";
	if (status.value !== "pending" && !product.value?.publishedAt) return "not-found-error";
	return "main-content";
});

const productImage = computed(() => {
	return product.value?.images?.images?.[0];
});

const ctaBgColor = computed(() => {
	if (product.value?.pattern) {
		return randomTailwindColor(product.value.pattern.id, "bg", 700);
	}
	return "bg-black";
});

// Product variants computed properties
const productVariantsPages = computed(() => {
	const variants = productVariants.value;
	const prod = product.value;
	if (!variants?.pages || !prod?.pages) return [];

	return variants.pages
		.filter(({ productVariant, id }) => !!productVariant || id === prod?.pages?.id)
		.map((pages) => ({
			id: pages.id,
			name: pages.name,
			iconUrl: pages.icon?.url,
			productId: pages.productVariant?.id,
			productSlug: pages.productVariant?.slug,
			active: prod?.pages?.id === pages.id
		}));
});

const productVariantsRuling = computed(() => {
	const variants = productVariants.value;
	const prod = product.value;
	if (!variants?.ruling || !prod?.ruling) return [];

	return variants.ruling
		.filter(({ productVariant, id }) => !!productVariant || id === prod?.ruling?.id)
		.map((ruling) => ({
			id: ruling.id,
			name: ruling.name,
			iconUrl: ruling.icon?.url,
			productId: ruling.productVariant?.id,
			productSlug: ruling.productVariant?.slug,
			active: prod?.ruling?.id === ruling.id
		}));
});

const productVariantsCover = computed(() => {
	const variants = productVariants.value;
	const prod = product.value;
	if (!variants?.cover || !prod?.cover) return [];

	return variants.cover
		.filter(({ productVariant, id }) => !!productVariant || id === prod?.cover?.id)
		.map((cover) => ({
			id: cover.id,
			name: cover.name,
			iconUrl: cover.icon?.url,
			productId: cover.productVariant?.id,
			productSlug: cover.productVariant?.slug,
			active: prod?.cover?.id === cover.id
		}));
});

const productVariantsPatterns = computed(() => {
	const variants = patternVariants.value;
	if (!variants?.patterns) return [];

	return variants.patterns
		.filter(({ productVariant }) => !!productVariant)
		.map((pattern) => ({
			id: pattern.id,
			name: pattern.name,
			imageUrl: pattern.image?.url,
			productId: pattern.productVariant?.id,
			productSlug: pattern.productVariant?.slug,
			product: pattern.productVariant
		}));
});

// Testimonials data
const testimonials: Testimonial[] = [
	{
		name: "Maria S.",
		purpose: "Skizzenbuch",
		comment: "Endlich ein Papier, das meine Aquarellstifte aushält. Kein Durchdrücken, nichts wellt sich. Hab schon das dritte bestellt.",
		rating: 5
	},
	{
		name: "Thomas W.",
		purpose: "Tagebuch",
		comment: "Schreibe seit Jahren Tagebuch und das hier ist mit Abstand das beste Notizbuch, das ich hatte. Liegt super in der Hand und die Seiten sind angenehm dick.",
		rating: 5
	},
	{
		name: "Julia B.",
		purpose: "Studium",
		comment: "Benutze es für Vorlesungsmitschriften. Das Papier ist top, mein Füller schmiert nicht. Sehr zufrieden!",
		rating: 4
	},
	{
		name: "Sophia K.",
		purpose: "Bullet Journal",
		comment: "Die Bindung ist echt gut, das Buch bleibt flach liegen beim Schreiben. Und ich mag, dass es in Deutschland hergestellt wird.",
		rating: 5
	},
	{
		name: "Lukas M.",
		purpose: "Arbeit",
		comment: "Nutze es für Meeting-Notizen. Sieht professionell aus und hält was aus. Hab's jetzt seit 8 Monaten täglich dabei.",
		rating: 5
	}
];

// Aggregate rating computed
const aggregateRating = computed(() => {
	if (!testimonials.length) return null;

	const totalRating = testimonials.reduce((sum, testimonial) => sum + testimonial.rating, 0);
	const ratingCount = testimonials.length;

	return {
		ratingValue: (totalRating / ratingCount).toFixed(1),
		ratingCount: ratingCount.toString(),
		reviewCount: ratingCount.toString()
	};
});

function formatPriceForSchema(price: number) {
	return price.toString().replace(",", ".");
}

function getPriceValidUntilDate() {
	const date = new Date();
	date.setFullYear(date.getFullYear() + 1);
	return date.toISOString().split("T")[0];
}

function getProductUrl() {
	if (import.meta.client) {
		return `${window.location.origin}/details/${slug.value}`;
	}
	return `/details/${slug.value}`;
}

function stripHtml(html: string): string {
	return html.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
}

function getProductDescription() {
	let description = "";

	if (product.value?.cover?.copyText) {
		const copyText = product.value.cover.copyText;

		if (copyText.details) description += stripHtml(copyText.details) + " ";
		if (copyText.format) description += "Format: " + copyText.format + ". ";
		if (copyText.paper) description += "Papier: " + copyText.paper + ". ";
		if (copyText.cover) description += "Einband: " + copyText.cover + ". ";
		if (copyText.banderole) description += "Banderole: " + copyText.banderole + ". ";
	}

	return description.trim() || product.value?.name || "";
}

interface VariantItem {
	id: number;
	name: string;
	active: boolean;
	productSlug?: string;
}

function handleVariantClick(type: string, variant: VariantItem) {
	if (!variant.active) {
		isChangingVariant.value = true;
	}
	trackEvent(`product-change-${type}-clicked`, {
		product: product.value?.id,
		label: variant.name
	});
}

function trackScrolling() {
	if (hasScrolled100.value) return;

	const progress = scrollProgress();

	if (progress >= 50 && !hasScrolled50.value) {
		trackEvent("product-details-scrolled-50");
		hasScrolled50.value = true;
	}

	if (progress === 100) {
		trackEvent("product-details-scrolled-100");
		hasScrolled100.value = true;
	}
}

async function addToCart() {
	if (!product.value?.id) return;

	trackEvent("product-details-add-to-cart-clicked", {
		product: product.value.id,
		price: product.value.totalProductPrice
	});

	try {
		isAddingToCart.value = true;
		await cartAddProduct(product.value.id);
		trackEvent("product-details-add-to-cart-succeeded", {
			product: product.value.id
		});
		navigateTo("/cart");
	} catch (error) {
		console.error(`Could not add product ${product.value.id} to cart:`, error);
		trackEvent("product-details-add-to-cart-failed", {
			product: product.value.id
		});
	} finally {
		isAddingToCart.value = false;
	}
}

// Lifecycle hooks
onMounted(() => {
	window.addEventListener("scroll", trackScrolling);

	// Track product view
	if (product.value?.id) {
		trackEvent("product-viewed", {
			productId: product.value.id,
			productSlug: slug.value,
			productName: product.value.name,
			price: product.value.totalProductPrice,
			coverType: product.value.cover?.name
		});
	}
});

onUnmounted(() => {
	window.removeEventListener("scroll", trackScrolling);
});

// SEO
useSeoMeta({
	title: () => `${product.value?.name ?? "Produkt"} | MUELLERPRINTS`,
	description: () => getProductDescription(),
	ogTitle: () => product.value?.name,
	ogDescription: () => getProductDescription(),
	ogImage: () => productImage.value?.url,
	ogType: "product"
});
</script>
