'use client';

import { useMemo } from 'react';
import React from 'react';
import { twMerge } from 'tailwind-merge';

import ImpressionLogger, {
  ImpressionLoggerConfig,
} from '@/components/ImpressionLogger';
import HeroCarousel from '@/components/promos/HeroCarousel';
import { BannerSection, BannerWebItem } from '@/types/bannerTypes';

import { BannerContent } from './BannerContent';

export interface DynamicBannerProps {
  section: BannerSection;
  collapsed?: boolean;
  onCollapseChange?: (collapsed: boolean) => void;
  className?: string;
}

const DynamicBanner: React.FC<DynamicBannerProps> = React.memo(
  ({ section, collapsed, onCollapseChange, className }) => {
    // "Visible" in this case doesn't mean currently visible in the viewport, it just
    // means the item is eligible to appear in the banner. i.e. the server only sends items
    // with visible = True up to the client.
    const visibleItems = useMemo(
      () =>
        section.items.filter(
          // Not a rigorous type check, but we can assume that we're only dealing with web items
          (item): item is BannerWebItem => item.visible ?? false
        ),
      [section.items]
    );

    // Impression logger config for tracking banner visibility
    const impressionLoggerConfig = useMemo<ImpressionLoggerConfig[]>(
      () => [
        {
          event: {
            actionName: 'DynamicBannerSeen',
            context: {
              itemsContained: visibleItems
                .map((item) => item.id ?? '')
                .filter((id): id is string => !!id),
            },
          },
          threshold: 0.95,
        },
        {
          event: {
            actionName: 'DynamicBannerPartiallySeen',
            context: {
              itemsContained: visibleItems
                .map((item) => item.id ?? '')
                .filter((id): id is string => !!id),
            },
          },
          threshold: 0.25,
        },
      ],
      [visibleItems]
    );

    // Multiple items - render as carousel (must be before early returns)
    const carouselItems = useMemo(
      () =>
        visibleItems.map(
          (item) =>
            function CarouselItem() {
              return (
                <BannerContent
                  className='rounded-none' // rounding is handled by the carousel component
                  bannerItem={item}
                  collapsed={collapsed}
                  onCollapseChange={onCollapseChange}
                />
              );
            }
        ),
      [visibleItems, collapsed, onCollapseChange]
    );

    // If no visible items, don't render anything
    if (visibleItems.length === 0) {
      return null;
    }

    // If single item, render directly
    if (visibleItems.length === 1) {
      return (
        <ImpressionLogger configs={impressionLoggerConfig}>
          <BannerContent
            bannerItem={visibleItems[0]}
            collapsed={collapsed}
            onCollapseChange={onCollapseChange}
            className={className}
          />
        </ImpressionLogger>
      );
    }

    return (
      <ImpressionLogger configs={impressionLoggerConfig}>
        <HeroCarousel
          autoplayDelay={7000}
          loop={true}
          items={carouselItems}
          collapsed={collapsed}
          onCollapseChange={onCollapseChange}
          className={twMerge('mb-4', className)}
        />
      </ImpressionLogger>
    );
  }
);

DynamicBanner.displayName = 'DynamicBanner';

export default DynamicBanner;
