/**
 * GalleryElement Component
 *
 * Gallery element with header image, title, info spans, and grid of image cards.
 * Renders with unified wrapper styling + content using section-specific styles.
 */

import React, { useMemo } from 'react';
import type { CSSProperties } from 'react';
import type {
  CanvasElement,
  GalleryCard,
  GalleryInfoSpan,
} from '../../../types/constructor';
import { resolveAssetPlaybackUrl } from '../../../lib/assetUrl';
import {
  buildGalleryHeaderStyle,
  buildGalleryTitleStyle,
  buildGallerySpanStyle,
  buildGallerySpanGridStyle,
  buildGalleryCardStyle,
  buildGalleryCardTitleStyle,
  buildGalleryCardGridStyle,
  GALLERY_SECTION_DEFAULTS,
} from '../../../lib/gallerySectionStyles';
import { useBackdropEffect } from '../../../hooks/useBackdropEffect';

/** Convert CSS textAlign to flexbox justifyContent */
const textAlignToJustify = (textAlign?: string): string => {
  switch (textAlign) {
    case 'left':
      return 'flex-start';
    case 'right':
      return 'flex-end';
    default:
      return 'center';
  }
};

interface GalleryElementProps {
  element: CanvasElement;
  resolveUrl?: (url: string | undefined) => string;
  className: string;
  style: CSSProperties;
  onCardClick?: (cardIndex: number) => void;
}

const GalleryElement: React.FC<GalleryElementProps> = ({
  element,
  resolveUrl,
  className,
  style,
  onCardClick,
}) => {
  const resolve = resolveUrl ?? resolveAssetPlaybackUrl;
  const cards: GalleryCard[] = element.galleryCards || [];
  const infoSpans: GalleryInfoSpan[] = element.galleryInfoSpans || [];
  const headerImageUrl = element.galleryHeaderImageUrl;
  const headerText = element.galleryHeaderText;
  const title = element.galleryTitle;

  // Build section styles from element properties
  const headerStyle = useMemo(
    () => buildGalleryHeaderStyle(element),
    [element],
  );
  const titleStyle = useMemo(() => buildGalleryTitleStyle(element), [element]);
  const spanStyle = useMemo(() => buildGallerySpanStyle(element), [element]);
  const spanGridStyle = useMemo(
    () => buildGallerySpanGridStyle(element),
    [element],
  );
  const cardStyle = useMemo(() => buildGalleryCardStyle(element), [element]);
  const cardTitleStyle = useMemo(
    () => buildGalleryCardTitleStyle(element),
    [element],
  );
  const cardGridStyle = useMemo(
    () => buildGalleryCardGridStyle(element),
    [element],
  );

  // Build wrapper style from general element styles with gallery defaults
  const wrapperDefaults = GALLERY_SECTION_DEFAULTS.wrapper;

  // Use portal-based backdrop for blur effect (works around CSS transform stacking context issue)
  const backdropBorderRadius =
    (style.borderRadius as string) ||
    (wrapperDefaults.borderRadius as string) ||
    '0.75rem';
  const backdropBackgroundColor =
    (style.backgroundColor as string) ||
    (wrapperDefaults.backgroundColor as string) ||
    'rgba(0, 0, 0, 0.6)';
  const backdropFilterValue =
    (wrapperDefaults.backdropFilter as string) || 'blur(4px)';
  const { ref: backdropRef, isPortalAvailable } = useBackdropEffect({
    enabled: true,
    backdropFilter: backdropFilterValue,
    backgroundColor: backdropBackgroundColor,
    borderRadius: backdropBorderRadius,
  });

  // Wrapper style - backdrop effects handled by portal when available,
  // otherwise fall back to inline styles (may not work with CSS transforms)
  const wrapperStyle: CSSProperties = useMemo(
    () => ({
      display: 'flex',
      flexDirection: 'column',
      // When portal is available, it handles background + blur, so use transparent here
      // When portal is not available, fall back to inline styles
      backgroundColor: isPortalAvailable
        ? 'transparent'
        : backdropBackgroundColor,
      backdropFilter: isPortalAvailable ? undefined : backdropFilterValue,
      WebkitBackdropFilter: isPortalAvailable ? undefined : backdropFilterValue,
      padding: style.padding || wrapperDefaults.padding,
      borderRadius: style.borderRadius || wrapperDefaults.borderRadius,
      border: style.border,
      gap: style.gap || wrapperDefaults.gap,
      // Visual properties that should apply to the wrapper, not outer positioning div
      boxShadow: style.boxShadow,
      opacity: style.opacity,
      // Inheritable text styles - cascade to child sections
      color: style.color,
      fontSize: style.fontSize,
      fontWeight: style.fontWeight,
      lineHeight: style.lineHeight,
    }),
    [
      isPortalAvailable,
      backdropBackgroundColor,
      backdropFilterValue,
      style.padding,
      style.borderRadius,
      style.border,
      style.gap,
      style.boxShadow,
      style.opacity,
      style.color,
      style.fontSize,
      style.fontWeight,
      style.lineHeight,
      wrapperDefaults,
    ],
  );

  // Extract wrapper-related styles from outer style (they go to wrapper, not outer div)
  const {
    backgroundColor: _bg,
    padding: _pad,
    borderRadius: _radius,
    border: _border,
    gap: _gap,
    boxShadow: _shadow,
    opacity: _opacity,
    color: _color,
    fontSize: _fontSize,
    fontWeight: _fontWeight,
    lineHeight: _lineHeight,
    ...outerStyle
  } = style;

  return (
    <div className={className} style={outerStyle}>
      <div ref={backdropRef} className='min-w-[200px]' style={wrapperStyle}>
        {/* Header: image takes priority, otherwise render text */}
        {/* Header styles (border, borderRadius, dimensions) apply to both image and text modes */}
        {headerImageUrl ? (
          <div style={{ ...headerStyle, padding: 0, overflow: 'hidden' }}>
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={resolve(headerImageUrl)}
              alt=''
              className='object-cover'
              style={{
                width: '100%',
                height: headerStyle.height || 'auto',
              }}
              draggable={false}
            />
          </div>
        ) : headerText ? (
          <div style={headerStyle}>{headerText}</div>
        ) : null}

        {/* Title */}
        {title && <div style={titleStyle}>{title}</div>}

        {/* Info spans */}
        {infoSpans.length > 0 && (
          <div style={spanGridStyle}>
            {infoSpans.map((span) => {
              // For icon spans, remove padding so image fills container
              const spanItemStyle = span.iconUrl
                ? { ...spanStyle, padding: 0, overflow: 'hidden' }
                : spanStyle;

              return (
                <div
                  key={span.id}
                  className='flex items-center'
                  style={{
                    ...spanItemStyle,
                    justifyContent: textAlignToJustify(
                      spanStyle.textAlign as string,
                    ),
                  }}
                >
                  {span.iconUrl ? (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={resolve(span.iconUrl)}
                      alt=''
                      className='w-full h-full object-cover'
                      draggable={false}
                    />
                  ) : (
                    span.text
                  )}
                </div>
              );
            })}
          </div>
        )}

        {/* Gallery cards */}
        {cards.length > 0 && (
          <div style={cardGridStyle}>
            {cards.map((card, index) => {
              // Build card container style with aspect ratio and dimensions
              const cardContainerStyle: CSSProperties = {
                ...cardStyle,
                position: 'relative',
                overflow: 'hidden',
                minWidth: '50px',
                // Use aspect-ratio from cardStyle, fallback to 4/3
                aspectRatio: cardStyle.aspectRatio || '4/3',
                // Use minHeight from cardStyle, fallback to 40px
                minHeight: cardStyle.minHeight || '40px',
              };

              return (
                <div
                  key={card.id}
                  className={
                    onCardClick
                      ? 'cursor-pointer hover:ring-2 hover:ring-white hover:ring-offset-1 hover:ring-offset-black/50 transition-all'
                      : ''
                  }
                  style={cardContainerStyle}
                  onClick={(e) => {
                    if (onCardClick) {
                      e.stopPropagation();
                      onCardClick(index);
                    }
                  }}
                >
                  {card.imageUrl && (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img
                      src={resolve(card.imageUrl)}
                      alt={card.title || ''}
                      className='absolute inset-0 w-full h-full object-cover'
                      style={{ borderRadius: cardContainerStyle.borderRadius }}
                      draggable={false}
                    />
                  )}
                  {card.title && (
                    <div className='absolute inset-0 flex items-center justify-center'>
                      <span style={cardTitleStyle}>{card.title}</span>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
};

export default GalleryElement;
