/**
 * ============================================
 * SHOPWARE CMS PAGE RENDERER
 * ============================================
 * Renders a Shopware 6 Shopping Experiences CMS page.
 * Handles: sections → blocks → slots
 *
 * Supported block types:
 *   text, image, image-simple, image-slider, image-text, image-text-row, text-image, text-image-row, hero,
 *   image-gallery, image-two-column, image-two-column-boxed, image-three-column, image-three-column-boxed,
 *   image-three-column-rounded, image-three-column-boxed-background, image-three-column-full-sized, 
 *   image-four-column, image-four-column-boxed, image-grid, image-bubble-row, image-highlight-row, image-simple-grid,
 *   text-three-column, text-teaser-section, text-two-column,
 *   product-listing, product-three-col, product-two-col,
 *   product-four-col, product-slider, category-navigation,
 *   youtube-video, vimeo-video, form, html
 *
 * Each slot type has its own component under elements/:
 *   elements/CmsElementText
 *   elements/CmsElementImage
 *   elements/CmsElementImageSlider
 *   elements/CmsElementImageGallery
 *   elements/CmsElementProductBox
 *   elements/CmsElementProductListing
 *   elements/CmsElementYoutubeVideo
 *   elements/CmsElementVimeoVideo
 *   elements/CmsElementHtml
 *   elements/CmsElementCategoryNavigation
 *   elements/CmsElementProductSlider
 *   elements/form/CmsElementContactForm
 *   elements/form/CmsElementNewsletterForm
 *   elements/CmsElementBuyBox
 *   elements/CmsElementProductDescriptionReviews
 *   elements/CmsElementCrossSelling
 *   elements/CmsElementSidebarFilter
 */

import type { CSSProperties, ReactNode } from 'react';
import Image from 'next/image';
// ─── Element components ──────────────────────────────────────────────────────
import CmsElementText               from '@/components/cms/elements/CmsElementText';
import CmsElementImage              from '@/components/cms/elements/CmsElementImage';
import CmsElementImageSlider        from '@/components/cms/elements/CmsElementImageSlider';
import CmsElementImageGallery       from '@/components/cms/elements/CmsElementImageGallery';
import CmsElementProductBox         from '@/components/cms/elements/CmsElementProductBox';
import CmsElementProductListing     from '@/components/cms/elements/CmsElementProductListing';
import CmsElementYoutubeVideo       from '@/components/cms/elements/CmsElementYoutubeVideo';
import CmsElementVimeoVideo         from '@/components/cms/elements/CmsElementVimeoVideo';
import CmsElementHtml               from '@/components/cms/elements/CmsElementHtml';
import CmsElementCategoryNavigation from '@/components/cms/elements/CmsElementCategoryNavigation';
import CmsElementProductSlider      from '@/components/cms/elements/CmsElementProductSlider';
import CmsElementProductName              from '@/components/cms/elements/CmsElementProductName';
import CmsElementProductManufacturerLogo from '@/components/cms/elements/CmsElementProductManufacturerLogo';
import CmsElementContactForm        from '@/components/cms/elements/form/CmsElementContactForm';
import CmsElementNewsletterForm     from '@/components/cms/elements/form/CmsElementNewsletterForm';
import CmsElementBuyBox             from '@/components/cms/elements/CmsElementBuyBox';
import CmsElementProductDescriptionReviews from '@/components/cms/elements/CmsElementProductDescriptionReviews';
import CmsElementCrossSelling       from '@/components/cms/elements/CmsElementCrossSelling';
import CmsElementSidebarFilter      from '@/components/cms/elements/CmsElementSidebarFilter';

// ─── Type helpers ────────────────────────────────────────────────────────────

interface CmsSlot {
  id: string;
  type: string;
  slot: string;
  data?: any;
  config?: any;
}

interface CmsBlock {
  id: string;
  type: string;
  position: number;
  slots: CmsSlot[];
  backgroundColor?: string | null;
  backgroundMedia?: any;
  cssClass?: string | null;
  marginTop?: string | null;
  marginRight?: string | null;
  marginBottom?: string | null;
  marginLeft?: string | null;
  visibility?: {
    mobile?: boolean;
    tablet?: boolean;
    desktop?: boolean;
  } | null;
  sectionPosition?: 'sidebar' | 'main'; // For sidebar layout sections
}

interface CmsSection {
  id: string;
  type: string; // 'default' | 'sidebar'
  position: number;
  blocks: CmsBlock[];
  backgroundColor?: string | null;
  backgroundMedia?: any;
  cssClass?: string | null;
  sizingMode?: string; // 'boxed' | 'full_width'
  marginTop?: string | null;
  marginBottom?: string | null;
  paddingTop?: string | null;
  paddingBottom?: string | null;
  paddingLeft?: string | null;
  paddingRight?: string | null;
}

// ─── Resolve a slot by name from a block ─────────────────────────────────────

function getSlot(block: CmsBlock, slotName: string): CmsSlot | undefined {
  return block.slots.find((s) => s.slot === slotName);
}

/**
 * Resolve the media object of an image slot. Mirrors the lookup in
 * CmsElementImage — Shopware may nest the real media under `media.media`.
 */
function getSlotMedia(slot?: CmsSlot): any {
  if (!slot) return null;
  const rawMedia = slot.data?.media;
  return rawMedia?.media ?? rawMedia ?? null;
}

/**
 * Normalise Shopware slot type — the API returns short names like "text", "image",
 * while some versions use "cms-text", "cms-image". We strip the "cms-" prefix so
 * we always match the short form.
 */
function normaliseSlotType(raw: string): string {
  return raw.replace(/^cms[-_]/, '').replace(/_/g, '-');
}

/**
 * In the product-gallery-buybox block the gallery must render at a FIXED height
 * (like the Shopware storefront) instead of the image's full natural height.
 * Shopware's "standard" display mode lets the image grow, so when no explicit
 * mode is set we switch the gallery to a contained, fixed-height box. The
 * merchant's own min-height is respected; otherwise it falls back to 430px
 * (Shopware's default product-gallery min-height). Cover/contain configs
 * already produce a fixed height and are left untouched.
 */
function withFixedGalleryHeight(slot: CmsSlot): CmsSlot {
  const cfg = slot.config ?? {};
  const mode: string | undefined = cfg.displayMode?.value;
  const minH: string | undefined = cfg.minHeight?.value;
  const hasMinH = !!minH && minH !== '0px';

  if (!mode || mode === 'standard') {
    return {
      ...slot,
      config: {
        ...cfg,
        displayMode: { value: 'contain' },
        minHeight: { value: hasMinH ? minH : '430px' },
      },
    };
  }
  return slot;
}

function renderSlot(slot: CmsSlot | undefined): ReactNode {
  if (!slot) return null;
  const rawType = slot.type ?? slot.data?.apiAlias ?? '';
  const type = normaliseSlotType(rawType);
  const elementClass = `cms-element cms-element-${type.replace(/_/g, '-')}`;

  const renderElement = () => {
    switch (type) {
      case 'text':
        return <CmsElementText slot={slot} />;
      case 'image':
        return <CmsElementImage slot={slot} />;
      case 'image-slider':
        return <CmsElementImageSlider slot={slot} />;
      case 'image-gallery':
        return <CmsElementImageGallery slot={slot} />;
      case 'product-name':
        return <CmsElementProductName slot={slot} />;
      case 'product-manufacturer-logo':
      case 'manufacturer-logo':
        return <CmsElementProductManufacturerLogo slot={slot} />;
      case 'product-box':
        return <CmsElementProductBox slot={slot} />;
      case 'product-listing':
        return <CmsElementProductListing slot={slot} />;
      case 'youtube-video':
        return <CmsElementYoutubeVideo slot={slot} />;
      case 'vimeo-video':
        return <CmsElementVimeoVideo slot={slot} />;
      case 'html':
        return <CmsElementHtml slot={slot} />;
      case 'category-navigation':
        return <CmsElementCategoryNavigation slot={slot} />;
      case 'form': {
        const formType = slot.config?.type?.value ?? slot.data?.type ?? 'contact';
        const title = slot.config?.title?.value ?? '';
        if (formType === 'contact') return <CmsElementContactForm title={title} />;
        if (formType === 'newsletter') return <CmsElementNewsletterForm title={title} />;
        return null;
      }
      // Product-detail slots — render from resolved slot.data (see resolveProductCmsSlots)
      case 'buy-box':
        return <CmsElementBuyBox slot={slot} />;
      case 'product-description-reviews':
        return <CmsElementProductDescriptionReviews slot={slot} />;
      case 'cross-selling':
        return <CmsElementCrossSelling slot={slot} />;
      // Listing-layout filter — renders when aggregations are injected into the slot
      case 'sidebar-filter':
        return <CmsElementSidebarFilter slot={slot} />;
      // Still delegated to the dedicated pages
      case 'listing':
      case 'product-image-gallery':
        return null;
      default:
        if (process.env.NODE_ENV === 'development') {
          return (
            <div className="border border-dashed border-yellow-400 bg-yellow-50 p-3 rounded text-xs text-yellow-700">
              Unknown slot type: <strong>{rawType}</strong>
              <pre className="mt-1 text-xs overflow-auto max-h-32">{JSON.stringify(slot.data, null, 2)}</pre>
            </div>
          );
        }
        return null;
    }
  };

  const element = renderElement();
  if (!element) return null;

  return (
    <div className={elementClass}>
      {element}
    </div>
  );
}

// ─── Block visibility ────────────────────────────────────────────────────────
// Shopware device breakpoints (Bootstrap-based):
//   Mobile  : < 768px   → Tailwind: below md
//   Tablet  : 768–1279px → Tailwind: md to xl
//   Desktop : ≥ 1280px   → Tailwind: xl+
function getVisibilityClass(v?: CmsBlock['visibility']): string {
  if (!v) return '';
  const m = v.mobile  !== false;
  const t = v.tablet  !== false;
  const d = v.desktop !== false;

  if ( m &&  t &&  d) return '';
  if (!m && !t && !d) return 'hidden';

  const parts: string[] = [];
  if (!m)        parts.push('hidden');
  if (!m &&  t)  parts.push('md:block');
  if ( m && !t)  parts.push('md:hidden');
  if (!t &&  d)  parts.push('xl:block');
  if ( t && !d)  parts.push('xl:hidden');
  return parts.join(' ');
}

// ─── Block renderers ─────────────────────────────────────────────────────────

// ─── Block wrapper with type class ──────────────────────────────────────────

function BlockWithClass({ block, children, className = '' }: { block: CmsBlock; children: ReactNode; className?: string }) {
  const blockClass = `cms-block cms-block-${block.type.replace(/_/g, '-')}`;
  const blockStyle: CSSProperties = {
    backgroundColor: block.backgroundColor ?? undefined,
    marginTop: block.marginTop ?? undefined,
    marginBottom: block.marginBottom ?? undefined,
    marginLeft: block.marginLeft ?? undefined,
    marginRight: block.marginRight ?? undefined,
  };
  
  return (
    <div className={`${blockClass} ${className}`.trim()} style={blockStyle}>
      {children}
    </div>
  );
}

// ─── CMS Block renderer ──────────────────────────────────────────────────────

function CmsBlock({ block }: { block: CmsBlock }) {
  const blockStyle: CSSProperties = {
    backgroundColor: block.backgroundColor ?? undefined,
    marginTop: block.marginTop ?? undefined,
    marginBottom: block.marginBottom ?? undefined,
    marginLeft: block.marginLeft ?? undefined,
    marginRight: block.marginRight ?? undefined,
  };

  switch (block.type) {
    // ── Plain text ────────────────────────────────────────────────────────
    case 'text': {
      const slot = getSlot(block, 'content');
      return (
        <BlockWithClass block={block}>
          {renderSlot(slot)}
        </BlockWithClass>
      );
    }

    // ── Single image ──────────────────────────────────────────────────────
    case 'image':
    case 'image-simple': {
      const slot = getSlot(block, 'image') ?? block.slots[0];
      return (
        <BlockWithClass block={block}>
          {renderSlot(slot)}
        </BlockWithClass>
      );
    }

    // ── Two column images, boxed ───────────────────────────────────────────
    case 'image-two-column':
    case 'image-two-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-full bg-white p-4 rounded-lg overflow-hidden border border-surface-100">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Three column images, boxed ────────────────────────────────────────
    case 'image-three-column':
    case 'image-three-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-full bg-white p-4 rounded-lg overflow-hidden border border-surface-100">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Three column images, full-sized ───────────────────────────────────
    case 'image-three-column-full-sized':
    case 'image-three-column-full': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="flex flex-wrap gap-0" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-1/3 overflow-hidden">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Four column images, boxed ─────────────────────────────────────────
    case 'image-four-column':
    case 'image-four-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-full bg-white p-4 rounded-lg overflow-hidden border border-surface-100">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Image grid ──────────────────────────────────────────────────────────
    case 'image-grid': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-full overflow-hidden rounded-lg">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Hero / full-width image ───────────────────────────────────────────
    case 'hero':
    case 'image-hero': {
      const imgSlot  = getSlot(block, 'background') ?? getSlot(block, 'image') ?? block.slots.find(s => s.type === 'cms-image');
      const textSlot = getSlot(block, 'content')    ?? getSlot(block, 'text')  ?? block.slots.find(s => s.type === 'cms-text');
      const media = imgSlot?.data?.media;

      return (
        <div className="relative w-full overflow-hidden rounded-xl" style={{ minHeight: '360px', ...blockStyle }}>
          {media?.url && (
            <Image
              src={media.url}
              alt={media.alt ?? ''}
              fill
              className="object-cover"
              priority
            />
          )}
          {media?.url && <div className="absolute inset-0 bg-black/40" />}
          {textSlot && (
            <div className="relative z-10 flex items-center justify-center h-full min-h-[360px] p-8 text-white">
              <div className="max-w-2xl text-center">
                <div
                  className="prose prose-invert prose-lg max-w-none"
                  dangerouslySetInnerHTML={{ __html: textSlot.data?.content ?? textSlot.config?.content?.value ?? '' }}
                />
              </div>
            </div>
          )}
        </div>
      );
    }

    // ── Image + Text, boxed (image left, text right) ─────────────────────
    case 'image-text': {
      const imgSlot = getSlot(block, 'left') ?? getSlot(block, 'image');
      const txtSlot = getSlot(block, 'right') ?? getSlot(block, 'text') ?? getSlot(block, 'content');
      return (
        <div className="grid md:grid-cols-2 gap-8 items-center" style={blockStyle}>
          <div>{renderSlot(imgSlot)}</div>
          <div>{renderSlot(txtSlot)}</div>
        </div>
      );
    }

    // ── Image + Text, full-sized (image left, text right) ────────────────
    case 'image-text-row': {
      const imgSlot = getSlot(block, 'left') ?? getSlot(block, 'image');
      const txtSlot = getSlot(block, 'right') ?? getSlot(block, 'text') ?? getSlot(block, 'content');
      return (
        <div className="grid md:grid-cols-2 gap-8 items-start" style={blockStyle}>
          <div>{renderSlot(imgSlot)}</div>
          <div>{renderSlot(txtSlot)}</div>
        </div>
      );
    }

    // ── Text + Image, boxed (text left, image right) ──────────────────────
    case 'text-image': {
      const txtSlot = getSlot(block, 'left') ?? getSlot(block, 'text') ?? getSlot(block, 'content');
      const imgSlot = getSlot(block, 'right') ?? getSlot(block, 'image');
      return (
        <div className="grid md:grid-cols-2 gap-8 items-center" style={blockStyle}>
          <div>{renderSlot(txtSlot)}</div>
          <div>{renderSlot(imgSlot)}</div>
        </div>
      );
    }

    // ── Text + Image, full-sized (text left, image right) ────────────────
    case 'text-image-row': {
      const txtSlot = getSlot(block, 'left') ?? getSlot(block, 'text') ?? getSlot(block, 'content');
      const imgSlot = getSlot(block, 'right') ?? getSlot(block, 'image');
      return (
        <div className="grid md:grid-cols-2 gap-8 items-start" style={blockStyle}>
          <div>{renderSlot(txtSlot)}</div>
          <div>{renderSlot(imgSlot)}</div>
        </div>
      );
    }

    // ── Three columns, boxed ─────────────────────────────────────────────
    case 'image-three-column':
    case 'image-three-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="bg-white p-4 rounded-lg overflow-hidden border border-surface-100">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Two images side by side ────────────────────────────────────────────
    case 'image-two-column':
    case 'image-two-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4" style={blockStyle}>
          {imgSlots.map(s => <div key={s.id}>{renderSlot(s)}</div>)}
        </div>
      );
    }

    // ── Three images side by side ──────────────────────────────────────────
    case 'image-three-column':
    case 'image-three-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="bg-white p-4 rounded-lg overflow-hidden border border-surface-100">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Four images side by side ──────────────────────────────────────────
    case 'image-four-column':
    case 'image-four-column-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" style={blockStyle}>
          {imgSlots.map(s => <div key={s.id}>{renderSlot(s)}</div>)}
        </div>
      );
    }

    // ── Three columns with rounded corners ─────────────────────────────────
    case 'image-three-column-rounded': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="rounded-lg overflow-hidden">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Three columns with background ────────────────────────────────────
    case 'image-three-column-boxed-background': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4 p-4 bg-surface-50 rounded-lg" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="bg-white p-3 rounded">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Three columns full-sized (no padding/boxes) ───────────────────────
    case 'image-three-column-full-sized':
    case 'image-three-column-full': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-0" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-full overflow-hidden">
              <div className="h-full w-full">
                {renderSlot(s)}
              </div>
            </div>
          ))}
        </div>
      );
    }

    // ── Three cover images side by side (full-bleed row) ──────────────────
    // Each slot's CmsElementImage honours displayMode: 'cover' + minHeight
    // from the slot config, so the block just provides the 3-column grid.
    case 'image-three-cover':
    case 'image-three-cover-boxed': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-3 gap-0" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="w-full overflow-hidden">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Single cover image (full-bleed row) ───────────────────────────────
    case 'image-cover': {
      const slot = block.slots.find(s => normaliseSlotType(s.type) === 'image') ?? block.slots[0];
      return (
        <div className="w-full overflow-hidden" style={blockStyle}>
          {renderSlot(slot)}
        </div>
      );
    }

    // ── Image grid layout ────────────────────────────────────────────────
    case 'image-grid': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6" style={blockStyle}>
          {imgSlots.map(s => (
            <div key={s.id} className="overflow-hidden rounded-lg">
              {renderSlot(s)}
            </div>
          ))}
        </div>
      );
    }

    // ── Image bubble row (circular images side by side) ───────────────────
    case 'image-bubble-row': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div className="flex flex-wrap items-center justify-center gap-6 md:gap-10" style={blockStyle}>
          {imgSlots.map(s => {
            const media = getSlotMedia(s);
            if (!media?.url) return null;
            return (
              <div
                key={s.id}
                className="relative aspect-square w-40 sm:w-52 md:w-64 shrink-0 overflow-hidden rounded-full"
              >
                <Image
                  src={media.url}
                  alt={media.alt ?? media.title ?? ''}
                  fill
                  className="object-cover"
                />
              </div>
            );
          })}
        </div>
      );
    }

    // ── Image highlight row (framed images on a tinted band) ──────────────
    case 'image-highlight-row': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      return (
        <div
          className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 md:gap-8 bg-surface-100 p-6 md:p-10"
          style={blockStyle}
        >
          {imgSlots.map(s => {
            const media = getSlotMedia(s);
            if (!media?.url) return null;
            return (
              <div key={s.id} className="bg-white p-2 shadow-md">
                <div className="relative aspect-[4/3] overflow-hidden">
                  <Image
                    src={media.url}
                    alt={media.alt ?? media.title ?? ''}
                    fill
                    className="object-cover"
                  />
                </div>
              </div>
            );
          })}
        </div>
      );
    }

    // ── Image simple grid (two stacked left, one tall right) ──────────────
    case 'image-simple-grid': {
      const imgSlots = block.slots.filter(s => normaliseSlotType(s.type) === 'image');
      // Mobile: stack all images vertically (1 column)
      // Tablet+: 2×2 layout with first two images stacked left, third tall on right
      const placementDesktop = [
        'md:col-start-1 md:row-start-1',
        'md:col-start-1 md:row-start-2',
        'md:col-start-2 md:row-start-1 md:row-span-2',
      ];
      return (
        <div className="grid grid-cols-1 md:grid-cols-2 md:grid-rows-2 gap-4 md:min-h-[480px]" style={blockStyle}>
          {imgSlots.slice(0, 3).map((s, i) => {
            const media = getSlotMedia(s);
            if (!media?.url) return null;
            return (
              <div
                key={s.id}
                className={`relative overflow-hidden h-[240px] md:h-auto ${placementDesktop[i] ?? ''}`}
              >
                <Image
                  src={media.url}
                  alt={media.alt ?? media.title ?? ''}
                  fill
                  className="object-cover"
                />
              </div>
            );
          })}
        </div>
      );
    }

    // ── Product listing (full) ─────────────────────────────────────────────
    // ── Product heading (product name left + manufacturer logo right) ────
    case 'product-heading': {
      const nameSlot =
        getSlot(block, 'name') ??
        block.slots.find(s => normaliseSlotType(s.type) === 'product-name');
      const logoSlot =
        getSlot(block, 'manufacturer-logo') ??
        getSlot(block, 'manufacturerLogo') ??
        block.slots.find(s => {
          const t = normaliseSlotType(s.type);
          return t === 'product-manufacturer-logo' || t === 'manufacturer-logo';
        });
      return (
        <div style={blockStyle} className="flex items-center justify-between gap-4">
          <div className="flex-1">{renderSlot(nameSlot)}</div>
          {logoSlot && <div className="shrink-0">{renderSlot(logoSlot)}</div>}
        </div>
      );
    }

    case 'product-listing': {
      const slot = getSlot(block, 'content') ?? block.slots[0];
      return (
        <div style={blockStyle}>
          {renderSlot(slot)}
        </div>
      );
    }

    // ── Product slider ─────────────────────────────────────────────────────
    case 'product-slider': {
      const slot = getSlot(block, 'products') ?? block.slots[0];
      if (!slot) return null;
      return (
        <div style={blockStyle}>
          <CmsElementProductSlider slot={slot} />
        </div>
      );
    }

    // ── 2 product boxes ────────────────────────────────────────────────────
    case 'product-two-col': {
      const slots = block.slots.sort((a, b) => (a.slot < b.slot ? -1 : 1));
      return (
        <div className="grid grid-cols-2 gap-6" style={blockStyle}>
          {slots.map(s => <div key={s.id}>{renderSlot(s)}</div>)}
        </div>
      );
    }

    // ── 3 product boxes ────────────────────────────────────────────────────
    case 'product-three-col': {
      const slots = block.slots.sort((a, b) => (a.slot < b.slot ? -1 : 1));
      return (
        <div className="grid grid-cols-2 sm:grid-cols-3 gap-6" style={blockStyle}>
          {slots.map(s => <div key={s.id}>{renderSlot(s)}</div>)}
        </div>
      );
    }

    // ── 4 product boxes ────────────────────────────────────────────────────
    case 'product-four-col': {
      const slots = block.slots.sort((a, b) => (a.slot < b.slot ? -1 : 1));
      return (
        <div className="grid grid-cols-2 sm:grid-cols-4 gap-6" style={blockStyle}>
          {slots.map(s => <div key={s.id}>{renderSlot(s)}</div>)}
        </div>
      );
    }

    // ── Category navigation ────────────────────────────────────────────────
    case 'category-navigation': {
      const slot = getSlot(block, 'content') ?? block.slots[0];
      return (
        <div style={blockStyle}>
          {renderSlot(slot)}
        </div>
      );
    }

    // ── YouTube / Vimeo ────────────────────────────────────────────────────
    case 'youtube-video':
    case 'vimeo-video': {
      const slot = block.slots[0];
      return (
        <div style={blockStyle}>
          {renderSlot(slot)}
        </div>
      );
    }

    // ── Contact / newsletter form ──────────────────────────────────────────
    case 'form': {
      const slot = getSlot(block, 'content') ?? block.slots[0];
      return (
        <div style={blockStyle} className="py-8">
          {renderSlot(slot)}
        </div>
      );
    }

    // ── Custom HTML ────────────────────────────────────────────────────────
    case 'html': {
      const slot = getSlot(block, 'content') ?? block.slots[0];
      return (
        <div style={blockStyle}>
          {renderSlot(slot)}
        </div>
      );
    }

    // ── Image gallery + buy box (Shopware "Image gallery and buy box") ──────
    // Two columns: gallery on the left (fixed height), buy box on the right.
    case 'product-gallery-buybox':
    case 'gallery-buybox':
    case 'product-gallery': {
      const gallerySlot =
        block.slots.find((s) => normaliseSlotType(s.type) === 'image-gallery') ??
        getSlot(block, 'left');
      const buyBoxSlot =
        block.slots.find((s) => normaliseSlotType(s.type) === 'buy-box') ??
        getSlot(block, 'right');
      return (
        <div className="grid md:grid-cols-2 gap-8 lg:gap-12 items-start" style={blockStyle}>
          <div>{gallerySlot && renderSlot(withFixedGalleryHeight(gallerySlot))}</div>
          <div>{buyBoxSlot && renderSlot(buyBoxSlot)}</div>
        </div>
      );
    }

    // ── Fallback: render all slots ─────────────────────────────────────────
    default: {
      return (
        <div className="space-y-4" style={blockStyle}>
          {block.slots.map(s => (
            <div key={s.id}>{renderSlot(s)}</div>
          ))}
        </div>
      );
    }
  }
}

// ─── Sidebar section renderer ───────────────────────────────────────────────

function CmsSidebarSection({ section }: { section: CmsSection }) {
  const isFullWidth = section.sizingMode === 'full_width';
  const hasBgMedia = !!section.backgroundMedia?.url;

  const sectionStyle: CSSProperties = {
    backgroundColor: section.backgroundColor ?? undefined,
    marginTop: section.marginTop ?? undefined,
    marginBottom: section.marginBottom ?? undefined,
    paddingTop: section.paddingTop ?? undefined,
    paddingBottom: section.paddingBottom ?? undefined,
    paddingLeft: !isFullWidth ? undefined : (section.paddingLeft ?? undefined),
    paddingRight: !isFullWidth ? undefined : (section.paddingRight ?? undefined),
  };

  // Separate blocks by sectionPosition
  const sidebarBlocks = [...section.blocks]
    .filter((b) => (b as any).sectionPosition === 'sidebar')
    .sort((a, b) => a.position - b.position);

  const mainContentBlocks = [...section.blocks]
    .filter((b) => (b as any).sectionPosition === 'main' || !(b as any).sectionPosition)
    .sort((a, b) => a.position - b.position);

  const renderBlocksColumn = (blocks: CmsBlock[]) =>
    blocks.map((block) => {
      const visClass = getVisibilityClass(block.visibility);
      if (visClass === 'hidden') return null;
      if (visClass) {
        return (
          <div key={block.id} className={visClass}>
            <CmsBlock block={block} />
          </div>
        );
      }
      return <CmsBlock key={block.id} block={block} />;
    });

  const inner = (
    <div className={isFullWidth ? 'w-full' : 'max-w-7xl mx-auto px-6'}>
      <div className="grid grid-cols-1 lg:grid-cols-4 xl:grid-cols-3 gap-6">
        {/* Sidebar column: lg-4/12, xl-3/12 */}
        <div className="lg:col-span-1">
          <div className="space-y-6">{renderBlocksColumn(sidebarBlocks)}</div>
        </div>

        {/* Main content column: lg-8/12, xl-9/12 */}
        <div className="lg:col-span-3 xl:col-span-2">
          <div className="space-y-6">{renderBlocksColumn(mainContentBlocks)}</div>
        </div>
      </div>
    </div>
  );

  if (hasBgMedia) {
    return (
      <section
        className="relative"
        style={{
          ...sectionStyle,
          backgroundImage: `url(${section.backgroundMedia.url})`,
          backgroundSize: 'cover',
          backgroundPosition: 'center',
        }}
      >
        <div className="absolute inset-0 bg-black/30" />
        <div className="relative z-10">{inner}</div>
      </section>
    );
  }

  return <section style={sectionStyle}>{inner}</section>;
}

// ─── Default section renderer ────────────────────────────────────────────────

function CmsSection({ section }: { section: CmsSection }) {
  const isFullWidth = section.sizingMode === 'full_width';
  const hasBgMedia = !!section.backgroundMedia?.url;

  const sectionStyle: CSSProperties = {
    backgroundColor: section.backgroundColor ?? undefined,
    marginTop: section.marginTop ?? undefined,
    marginBottom: section.marginBottom ?? undefined,
    paddingTop: section.paddingTop ?? undefined,
    paddingBottom: section.paddingBottom ?? undefined,
    paddingLeft: !isFullWidth ? undefined : (section.paddingLeft ?? undefined),
    paddingRight: !isFullWidth ? undefined : (section.paddingRight ?? undefined),
  };

  const inner = (
    <div className={isFullWidth ? 'w-full' : 'max-w-7xl mx-auto px-6'}>
      {[...section.blocks]
        .sort((a, b) => a.position - b.position)
        .map((block) => {
          const visClass = getVisibilityClass(block.visibility);
          if (visClass === 'hidden') return null;
          if (visClass) {
            return (
              <div key={block.id} className={visClass}>
                <CmsBlock block={block} />
              </div>
            );
          }
          return <CmsBlock key={block.id} block={block} />;
        })}
    </div>
  );

  if (hasBgMedia) {
    return (
      <section
        className="relative"
        style={{
          ...sectionStyle,
          backgroundImage: `url(${section.backgroundMedia.url})`,
          backgroundSize: 'cover',
          backgroundPosition: 'center',
        }}
      >
        <div className="absolute inset-0 bg-black/30" />
        <div className="relative z-10">{inner}</div>
      </section>
    );
  }

  return <section style={sectionStyle}>{inner}</section>;
}

// ─── Main export ─────────────────────────────────────────────────────────────

interface CmsPageProps {
  sections: CmsSection[];
}

export default function CmsPage({ sections }: CmsPageProps) {
  if (!sections?.length) return null;

  return (
    <div>
      {[...sections]
        .sort((a, b) => a.position - b.position)
        .map((section) => {
          if (section.type === 'sidebar') {
            return <CmsSidebarSection key={section.id} section={section} />;
          }
          return <CmsSection key={section.id} section={section} />;
        })}
    </div>
  );
}
