/**
 * ============================================
 * PRODUCT DETAIL PAGE (PDP)
 * ============================================
 * Equivalent to: product detail page in Shopware
 * Route: /products/[id]
 * 
 * This uses Dynamic Routes in Next.js:
 * /products/abc123 → params.id = "abc123"
 * 
 * Like Shopware's {productId} route parameter
 */

import {
  getProduct,
  getProductConfigurator,
  getProductReviews,
  getProductCrossSelling,
  getProductProperties,
  resolveProductCmsSlots,
  groupRawOptions,
  formatPrice,
  getCategoryUrl,
  getProductUrl,
  getActiveLocalePrefix,
  ShopwareProduct,
  PropertyGroup,
  ProductReview,
  CrossSelling,
} from '@/lib/shopware-api';
import { redirect } from 'next/navigation';
import CmsPage from '@/components/cms/CmsPage';
import JsonLd from '@/components/JsonLd';
import { buildProductJsonLd, buildBreadcrumbJsonLd } from '@/lib/structured-data';
import CmsElementProductName from '@/components/cms/elements/CmsElementProductName';
import AddToCartButton from '@/components/product/AddToCartButton';
import WishlistButton from '@/components/product/WishlistButton';
import ProductImageGallery from '@/components/product/ProductImageGallery';
import ProductVariantSelector from '@/components/product/ProductVariantSelector';
import ProductDetailTabs from '@/components/product/ProductDetailTabs';
import ProductCrossSelling from '@/components/product/ProductCrossSelling';
import ReviewAnchor from '@/components/product/ReviewAnchor';
import Link from 'next/link';
import { Fragment } from 'react';
import type { Metadata } from 'next';

// Generate SEO metadata dynamically
export async function generateMetadata({
  params,
}: {
  params: Promise<{ id: string }>;
}): Promise<Metadata> {
  try {
    const { id } = await params;
    const { product } = await getProduct(id);
    return {
      title: product.translated?.name || product.name,
      description: product.translated?.description || product.description || '',
    };
  } catch {
    return { title: 'Product' };
  }
}

export default async function ProductDetailPage({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>;
  searchParams: Promise<{ categoryId?: string; _fromSeo?: string }>;
}) {
  const [{ id }, { categoryId: fromCategoryId, _fromSeo }] = await Promise.all([params, searchParams]);
  let product: ShopwareProduct | null = null;
  let configuratorElements: PropertyGroup[] = [];
  let initialReviews: ProductReview[] = [];
  let reviewTotal = 0;
  let crossSellings: CrossSelling[] = [];

  let productRawConfigurator: any[] | undefined;
  try {
    const response = await getProduct(id);
    product = response.product;
    productRawConfigurator = response.configurator;
  } catch (e) {
    console.error('Failed to fetch product:', e);
  }

  // Force the slug URL in the browser. When reached via the catch-all SEO
  // route, _fromSeo is set so we don't redirect (which would bounce the
  // user away from the URL they're already on).
  if (!_fromSeo && product) {
    const target = getProductUrl(product);
    // Only redirect if we built something nicer than /products/{id}
    if (!target.startsWith('/products/')) {
      const qs = fromCategoryId ? `?categoryId=${encodeURIComponent(fromCategoryId)}` : '';
      redirect(`${getActiveLocalePrefix()}${target}${qs}`);
    }
  }

  if (product) {
    const configuratorProductId = product.parentId || product.id;

    // Fetch configurator, reviews, and cross-selling in parallel
    const [, reviewsResult, crossSellingResult] = await Promise.all([
      (async () => {
        try {
          if (productRawConfigurator && productRawConfigurator.length > 0) {
            configuratorElements = groupRawOptions(productRawConfigurator).elements || [];
          }
          if (configuratorElements.length === 0) {
            const configurator = await getProductConfigurator(configuratorProductId);
            configuratorElements = configurator.elements || [];
          }
        } catch (e) {
          console.error('[PDP] Failed to fetch configurator:', e);
        }
      })(),
      getProductReviews(product.id, { limit: 10, page: 1 }).catch(() => null),
      getProductCrossSelling(product.id).catch(() => []),
    ]);

    if (reviewsResult) {
      initialReviews = reviewsResult.elements || [];
      reviewTotal = reviewsResult.total ?? 0;
    }
    crossSellings = crossSellingResult || [];
  }

  if (!product) {
    return (
      <div className="max-w-7xl mx-auto px-6 py-20 text-center">
        <h1 className="text-2xl font-bold">Product Not Found</h1>
        <p className="text-surface-500 mt-2">The product you&apos;re looking for doesn&apos;t exist.</p>
        <Link href="/" className="inline-block mt-6 text-brand-600 hover:text-brand-700 font-medium">
          Back to homepage
        </Link>
      </div>
    );
  }

  const name = product.translated?.name || product.name;
  const description = product.translated?.description || product.description;
  const properties = getProductProperties(product);
  const price = product.calculatedPrice?.unitPrice || product.price?.[0]?.gross || 0;
  const listPrice = product.calculatedPrice?.listPrice?.price;
  const manufacturer = product.manufacturer?.name;
  const deliveryTime = product.deliveryTime?.translated?.name || product.deliveryTime?.name;
  const shippingFree = product.shippingFree;
  const advancedPrices = product.calculatedPrices && product.calculatedPrices.length > 1
    ? product.calculatedPrices
    : null;
  // Parent ID for find-variant: if this is a variant use parentId, if parent use own id
  const parentId = product.parentId || product.id;

  // Use the category the user came from (passed via ?categoryId=) if it matches this product.
  // Falls back to the deepest category when no context is available (e.g. direct URL, search).
  const breadcrumbCategory =
    (fromCategoryId && product.categories?.find((c) => c.id === fromCategoryId)) ||
    (product.categories?.length
      ? [...product.categories].sort((a, b) => {
          const aDepth = a.breadcrumb?.length ?? a.level ?? 0;
          const bDepth = b.breadcrumb?.length ?? b.level ?? 0;
          return bDepth - aDepth;
        })[0]
      : undefined);

  // Shopware's breadcrumb array includes the root category (e.g. "Catalogue #1") as first item — skip it.
  // Result: ["Clothing", "Women"] which we render as: Home > Clothing > Women > Product
  const breadcrumbPath: string[] =
    breadcrumbCategory?.breadcrumb && breadcrumbCategory.breadcrumb.length > 1
      ? breadcrumbCategory.breadcrumb.slice(1)
      : breadcrumbCategory
      ? [breadcrumbCategory.name]
      : [];

  // Build deduplicated gallery image list (cover first, then media array).
  // Carry the original media dimensions so the gallery renders at the image's
  // natural aspect ratio (Shopware "standard" display mode) instead of a square.
  const dimsOf = (m: any): { width?: number; height?: number } => ({
    width: m?.metaData?.width ?? m?.width ?? undefined,
    height: m?.metaData?.height ?? m?.height ?? undefined,
  });
  const coverUrl = product.cover?.media?.url;
  const sortedMedia = [...(product.media || [])].sort((a, b) => a.position - b.position);
  const galleryImages: Array<{ url: string; alt: string | null; width?: number; height?: number }> = [];
  const seen = new Set<string>();
  if (coverUrl) {
    seen.add(coverUrl);
    galleryImages.push({ url: coverUrl, alt: product.cover?.media?.alt || null, ...dimsOf(product.cover?.media) });
  }
  for (const m of sortedMedia) {
    if (m.media?.url && !seen.has(m.media.url)) {
      seen.add(m.media.url);
      galleryImages.push({ url: m.media.url, alt: m.media.alt, ...dimsOf(m.media) });
    }
  }

  // ── SEO structured data (schema.org) ──────────────────────────────────────
  const localePrefix = getActiveLocalePrefix();
  const productPath = `${localePrefix}${getProductUrl(product)}`;
  const productJsonLd = buildProductJsonLd({
    product,
    name,
    description,
    price,
    images: galleryImages.map((g) => g.url),
    path: productPath,
    reviewCount: reviewTotal,
  });
  const breadcrumbJsonLd = buildBreadcrumbJsonLd([
    { name: 'Home', path: localePrefix || '/' },
    ...(breadcrumbCategory
      ? [{ name: breadcrumbCategory.name, path: `${localePrefix}${getCategoryUrl(breadcrumbCategory)}` }]
      : []),
    { name, path: productPath },
  ]);

  // Check if a full product CMS layout is assigned (not just headings)
  const rawCmsPageSections: any[] = (product as any).cmsPage?.sections?.elements
    ?? (product as any).cmsPage?.sections
    ?? [];

  // Detect if there are meaningful CMS blocks beyond just product-heading
  // (buy-box, gallery, description, cross-selling, etc.)
  const hasFullCmsLayout = rawCmsPageSections.some((section: any) =>
    (section.blocks?.elements ?? section.blocks ?? []).some((block: any) =>
      block.type !== 'product-heading'
    )
  );

  // If a full CMS layout is assigned, render it instead of the hardcoded layout
  if (hasFullCmsLayout && rawCmsPageSections.length > 0) {
    const resolved = resolveProductCmsSlots(rawCmsPageSections, product, {
      reviews: { elements: initialReviews, total: reviewTotal } as any,
      crossSellings,
    });
    return (
      <div>
        <div className="max-w-7xl mx-auto px-6 py-10">
          <JsonLd data={breadcrumbJsonLd ? [productJsonLd, breadcrumbJsonLd] : productJsonLd} />

          {/* Breadcrumb */}
          <nav className="text-sm text-surface-500 mb-6 flex items-center gap-1.5 flex-wrap">
            <Link href={getActiveLocalePrefix() || '/'} className="hover:text-surface-600 transition-colors">Home</Link>
            {breadcrumbPath.map((crumb, index) => {
              const isLast = index === breadcrumbPath.length - 1;
              return (
                <Fragment key={`${crumb}-${index}`}>
                  <svg className="w-3 h-3 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
                  </svg>
                  {isLast && breadcrumbCategory ? (
                    <Link href={`${getActiveLocalePrefix()}${getCategoryUrl(breadcrumbCategory)}`} className="hover:text-surface-600 transition-colors">
                      {crumb}
                    </Link>
                  ) : (
                    <span>{crumb}</span>
                  )}
                </Fragment>
              );
            })}
            <svg className="w-3 h-3 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
            </svg>
            <span className="text-surface-700 font-medium line-clamp-1">{name}</span>
          </nav>
        </div>

        {/* Render the full CMS layout */}
        <CmsPage sections={resolved} />
      </div>
    );
  }

  // Fallback: render hardcoded product detail layout
  return (
    <div className="max-w-7xl mx-auto px-6 py-10">
      <JsonLd data={breadcrumbJsonLd ? [productJsonLd, breadcrumbJsonLd] : productJsonLd} />

      {/* Breadcrumb */}
      <nav className="text-sm text-surface-500 mb-6 flex items-center gap-1.5 flex-wrap">
        <Link href={getActiveLocalePrefix() || '/'} className="hover:text-surface-600 transition-colors">Home</Link>
        {breadcrumbPath.map((crumb, index) => {
          const isLast = index === breadcrumbPath.length - 1;
          return (
            <Fragment key={`${crumb}-${index}`}>
              <svg className="w-3 h-3 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
              </svg>
              {isLast && breadcrumbCategory ? (
                <Link href={`${getActiveLocalePrefix()}${getCategoryUrl(breadcrumbCategory)}`} className="hover:text-surface-600 transition-colors">
                  {crumb}
                </Link>
              ) : (
                <span>{crumb}</span>
              )}
            </Fragment>
          );
        })}
        <svg className="w-3 h-3 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
        </svg>
        <span className="text-surface-700 font-medium line-clamp-1">{name}</span>
      </nav>

      {/* Product heading sections from CMS layout (all product-heading blocks) */}
      {(() => {
        // Keep only product-heading blocks; drop buy-box, gallery, reviews, etc.
        const headingSections = rawCmsPageSections
          .map((section: any) => ({
            ...section,
            blocks: (section.blocks?.elements ?? section.blocks ?? []).filter(
              (block: any) => block.type === 'product-heading'
            ),
          }))
          .filter((section: any) => section.blocks.length > 0);
        if (headingSections.length > 0) {
          const resolved = resolveProductCmsSlots(headingSections, product);
          return <CmsPage sections={resolved} />;
        }
        // Fallback: render a single product-heading using the product name directly
        return (
          <div className="mb-6">
            <CmsElementProductName
              slot={{
                id: 'product-heading-name',
                type: 'product-name',
                slot: 'name',
                data: { content: name },
                config: {
                  content: { source: 'mapped', value: 'product.name' },
                  verticalAlign: { source: 'static', value: null },
                },
              }}
            />
          </div>
        );
      })()}

      <div className="grid md:grid-cols-2 gap-8 lg:gap-12 items-start">
        {/* ---- Image Gallery ---- */}
        <ProductImageGallery images={galleryImages} productName={name} />

        {/* ---- Product Info ---- */}
        <div className="flex flex-col">
          {/* Manufacturer */}
          {manufacturer && (
            <p className="text-sm text-brand-600 font-semibold uppercase tracking-wider mb-2">
              {manufacturer}
            </p>
          )}

          {/* Rating */}
          {(product.ratingAverage || reviewTotal > 0) && (
            <ReviewAnchor ratingAverage={product.ratingAverage} reviewTotal={reviewTotal} />
          )}

          {/* Advanced Prices Table — Shopware quantity tier pricing */}
          {advancedPrices && (
            <div className="mb-4">
              <table className="w-full text-sm border-collapse">
                <thead>
                  <tr className="border-b border-surface-200">
                    <th className="text-left py-2 font-medium text-surface-700">Quantity</th>
                    <th className="text-right py-2 font-medium text-surface-700">Unit price</th>
                  </tr>
                </thead>
                <tbody>
                  {advancedPrices.map((tier, i) => {
                    const nextTier = advancedPrices[i + 1];
                    const label = nextTier
                      ? `To ${nextTier.quantity - 1}`
                      : `From ${tier.quantity}`;
                    return (
                      <tr key={i} className="border-b border-surface-100">
                        <td className="py-2 text-surface-600">{label}</td>
                        <td className="py-2 text-right text-surface-900 font-medium">
                          {formatPrice(tier.unitPrice)}*
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}

          {/* Price */}
          {price > 0 && !advancedPrices && (
            <div className="mb-4">
              <div className="flex items-baseline gap-3">
                <span className="text-3xl font-bold">{formatPrice(price)}</span>
                {listPrice && listPrice > price && (
                  <>
                    <span className="text-lg text-surface-400 line-through">{formatPrice(listPrice)}</span>
                    <span className="text-sm font-semibold text-red-500 bg-red-50 px-2 py-0.5 rounded-md">
                      -{Math.round(((listPrice - price) / listPrice) * 100)}%
                    </span>
                  </>
                )}
              </div>
            </div>
          )}

          {/* VAT & Shipping info */}
          {price > 0 && (
            <div className="mb-4">
              <p className="text-xs text-surface-500">
                Prices incl. VAT plus{' '}
                <Link href="/shipping-info" className="text-brand-500 hover:underline">shipping costs</Link>
              </p>
              {shippingFree && (
                <div className="flex items-center gap-1.5 mt-1.5 text-sm">
                  <span className="w-2 h-2 rounded-full bg-brand-500 flex-shrink-0" />
                  <span className="text-surface-600">Free shipping</span>
                </div>
              )}
            </div>
          )}

          {/* Delivery time */}
          {deliveryTime && (
            <div className="flex items-center gap-2 mb-4 text-sm">
              <span className="w-2.5 h-2.5 rounded-full bg-green-500 flex-shrink-0" />
              <span className="text-surface-600">Available, delivery time: {deliveryTime}</span>
            </div>
          )}

          {/* Variant Selector */}
          {configuratorElements.length > 0 && (
            <div className="mb-6">
              <ProductVariantSelector
                parentId={parentId}
                selectedOptionIds={product.optionIds || []}
                elements={configuratorElements}
              />
            </div>
          )}

          {/* Add to Cart — full width row like Shopware */}
          {price > 0 ? (
            <AddToCartButton productId={product.id} />
          ) : configuratorElements.length > 0 ? (
            <p className="text-sm text-surface-500">
              Please select your options above to see the price.
            </p>
          ) : null}

          {/* Wishlist — separate row below, text link style like Shopware */}
          <div className="mt-3">
            <WishlistButton productId={product.id} variant="detail" />
          </div>

          {/* Product number */}
          <p className="text-sm text-surface-500 mt-4 font-medium">
            Product number: {product.productNumber}
          </p>
        </div>
      </div>

      {/* Description & Reviews Tabs — full width like Shopware */}
      <div className="mt-12">
        <ProductDetailTabs
          productId={product.id}
          productName={name}
          description={description}
          properties={properties}
          initialReviews={initialReviews}
          initialTotal={reviewTotal}
          ratingAverage={product.ratingAverage}
        />
      </div>

      {/* Cross-Selling */}
      {crossSellings.length > 0 && (
        <ProductCrossSelling crossSellings={crossSellings} />
      )}
    </div>
  );
}
