function Showcase(props) {
  const variant = props.variant || 'default';
  const isHero = variant === 'hero';
  const sectionKey = props.sectionKey || 'atelierHero';
  const sectionId = props.sectionId || 'showcase';
  const copy = window.atelaGetCopySection('showcase');
  const heroCopy = isHero ? window.atelaGetCopySection(sectionKey) : null;
  const currentLocale = window.atelaGetCurrentLocale ? window.atelaGetCurrentLocale() : 'ko';
  const buildPageUrl = window.atelaBuildPageUrl || ((pageId, locale) => (
    pageId && pageId !== 'home' ? `/${locale}/${pageId}` : `/${locale}`
  ));
  const trackCtaClick = window.atelaTrackCtaClick;
  const titleLines = Array.isArray((isHero ? heroCopy?.titleLines : copy.titleLines))
    ? (isHero ? heroCopy.titleLines : copy.titleLines)
    : [isHero ? heroCopy?.title : copy.title];
  const heroTitlePrefix = isHero ? String(heroCopy?.titlePrefix || '').trim() : '';
  const heroTitleHighlight = isHero ? String(heroCopy?.titleHighlight || '').trim() : '';
  const heroTitleSuffix = isHero ? String(heroCopy?.titleSuffix || '').trim() : '';
  const heroTitleSuffixJoiner = /^[A-Za-z0-9]/.test(heroTitleSuffix) ? ' ' : '';
  const heroEyebrow = isHero ? String(heroCopy?.eyebrow || '').trim() : copy.eyebrow;
  const heroBody = isHero ? String(heroCopy?.body || '').trim() : '';
  const heroBodyLines = heroBody ? heroBody.split('\n') : [];
  const heroBodyPlacement = isHero ? heroCopy?.bodyPlacement || 'head' : 'head';
  const heroPrimaryCta = isHero ? String(heroCopy?.primaryCta || '').trim() : '';
  const heroPrimaryHref = heroPrimaryCta
    ? buildPageUrl(heroCopy?.primaryPageId || 'home', currentLocale)
    : '';
  const manifestItems = Array.isArray(window.atelaWantThisGallery) ? window.atelaWantThisGallery : [];
  const galleryItems = manifestItems.length
    ? manifestItems
    : copy.cards.map((card) => ({
        id: card.id,
        type: 'image',
        src: card.image,
        alt: card.alt,
      }));
  const loopItems = [];
  const minimumLoopLength = Math.max(galleryItems.length, 6);

  if (galleryItems.length) {
    for (let index = 0; index < minimumLoopLength; index += 1) {
      loopItems.push({
        ...galleryItems[index % galleryItems.length],
        loopId: `${galleryItems[index % galleryItems.length].id}-loop-${index}`,
      });
    }
  }

  const handleHeroPrimaryClick = () => {
    if (!trackCtaClick || !heroPrimaryCta || !heroPrimaryHref) return;
    trackCtaClick({
      sectionId,
      ctaId: `${sectionKey}_primary`,
      ctaLabel: heroPrimaryCta,
      destination: heroPrimaryHref,
    });
  };

  const heroBodyContent = isHero && heroBodyLines.length ? (
    <div className={`atelier-hero-copy${heroBodyPlacement === 'after-gallery' ? ' is-below-gallery' : ''}`}>
      <p>
        {heroBodyLines.map((line, index) => (
          <React.Fragment key={`${line}-${index}`}>
            {index > 0 ? <br /> : null}
            {line}
          </React.Fragment>
        ))}
      </p>
    </div>
  ) : null;

  const heroPrimaryAction = isHero && heroPrimaryCta ? (
    <div className="atela-hero-cta center atelier-hero-actions is-below-gallery">
      <a className="atela-btn-ink" href={heroPrimaryHref} onClick={handleHeroPrimaryClick}>
        {heroPrimaryCta}
      </a>
    </div>
  ) : null;

  return (
    <section id={sectionId} className={`atela-showcase${isHero ? ' is-hero' : ''}`}>
      <div className="atela-container">
        <div className="atela-showcase-head">
          <div className="atela-showcase-heading">
            {heroEyebrow ? <span className="atela-eyebrow">{heroEyebrow}</span> : null}
            <h2 className="atela-h2">
              {heroTitleHighlight ? (
                <>
                  {heroTitlePrefix}
                  <br />
                  <span className="hl">{heroTitleHighlight}</span>{heroTitleSuffixJoiner}{heroTitleSuffix}
                </>
              ) : (
                titleLines.map((line, index) => (
                  <React.Fragment key={`${line}-${index}`}>
                    {index > 0 ? <br /> : null}
                    {line}
                  </React.Fragment>
                ))
              )}
            </h2>
          </div>
          {heroBodyPlacement !== 'after-gallery' ? heroBodyContent : null}
        </div>

        <div className="showcase-gallery" aria-label={(isHero ? heroEyebrow : copy.galleryLabel) || copy.eyebrow}>
          <div className="showcase-loop-track">
            {[0, 1].map((groupIndex) => (
              <div
                key={`showcase-group-${groupIndex}`}
                className="showcase-loop-group"
                aria-hidden={groupIndex === 1}
              >
                {loopItems.map((item, cardIndex) => (
                  <figure
                    key={`${groupIndex}-${item.loopId}`}
                    className="showcase-loop-item"
                    style={{ '--showcase-order': cardIndex + 1 }}
                    aria-label={item.type === 'video' ? item.alt : undefined}
                  >
                    {item.type === 'video' ? (
                      <video
                        src={item.src}
                        poster={item.poster}
                        autoPlay
                        muted
                        loop
                        playsInline
                        preload="metadata"
                        aria-hidden="true"
                      />
                    ) : (
                      <img src={item.src} alt={item.alt} loading="lazy" decoding="async" />
                    )}
                  </figure>
                ))}
              </div>
            ))}
          </div>
        </div>

        {heroBodyPlacement === 'after-gallery' ? heroBodyContent : null}
        {heroBodyPlacement === 'after-gallery' ? heroPrimaryAction : null}
      </div>
    </section>
  );
}

window.Showcase = Showcase;
