'use client';

import React, { useState, useCallback, useMemo } from 'react';
import { twMerge } from 'tailwind-merge';
import clsx from 'clsx';
import { Image } from '@akinon/next/components/image';
import { Link } from '@akinon/next/components/link';
import type {
  ListHoverImageProps,
  IndicatorProps,
  HoverZoneProps
} from '../types';
import { mergeSettings } from '../utils';

function HoverZones({ count, href, onHover, customStyles }: HoverZoneProps) {
  return (
    <div
      className={twMerge(
        'absolute inset-0 flex cursor-pointer justify-between',
        customStyles?.hoverZoneContainer
      )}
    >
      {Array.from({ length: count }, (_, index) => (
        <Link
          href={href}
          key={index}
          className={twMerge('relative w-full', customStyles?.hoverZone)}
          onMouseEnter={() => onHover(index)}
          aria-label={`View image ${index + 1}`}
        />
      ))}
    </div>
  );
}

function Indicators({
  count,
  activeIndex,
  onSelect,
  customStyles,
  customRenderers
}: IndicatorProps) {
  if (count <= 1) return null;

  if (customRenderers?.renderIndicator) {
    return (
      <>
        {customRenderers.renderIndicator({
          count,
          activeIndex,
          onSelect
        })}
      </>
    );
  }

  return (
    <div
      className={twMerge(
        'absolute bottom-4 left-0 flex w-full justify-center',
        customStyles?.indicatorContainer
      )}
    >
      <ul
        className={twMerge(
          'flex gap-1.5 lg:gap-2',
          customStyles?.indicatorList
        )}
        role="tablist"
        aria-label="Product images"
      >
        {Array.from({ length: count }, (_, index) => {
          if (customRenderers?.renderIndicatorDot) {
            return (
              <li key={index} role="tab" aria-selected={activeIndex === index}>
                {customRenderers.renderIndicatorDot({
                  index,
                  isActive: activeIndex === index,
                  onClick: () => onSelect(index)
                })}
              </li>
            );
          }

          return (
            <li
              key={index}
              role="tab"
              aria-selected={activeIndex === index}
              className={twMerge(
                clsx(
                  'w-2.5 h-2.5 lg:w-3.5 lg:h-3.5 border rounded-full cursor-pointer transition-colors duration-200',
                  'border-white',
                  {
                    'bg-secondary border-transparent': activeIndex === index
                  }
                ),
                activeIndex === index
                  ? customStyles?.indicatorActive
                  : customStyles?.indicator
              )}
              onClick={() => onSelect(index)}
            />
          );
        })}
      </ul>
    </div>
  );
}

export function ListHoverImage({
  images,
  href,
  alt,
  width,
  height,
  fill,
  sizes,
  aspectRatio,
  maxImages,
  fallbackImage,
  className,
  settings: userSettings
}: ListHoverImageProps) {
  const settings = mergeSettings(userSettings);

  const resolvedMaxImages = maxImages ?? settings.maxImages;
  const resolvedFallback = fallbackImage ?? settings.fallbackImage;

  const visibleImages = useMemo(
    () => images?.slice(0, resolvedMaxImages) ?? [],
    [images, resolvedMaxImages]
  );

  const initialImageUrl = visibleImages[0]?.image || resolvedFallback;

  const [activeIndex, setActiveIndex] = useState(0);
  const [currentImageUrl, setCurrentImageUrl] = useState(initialImageUrl);

  const handleImageChange = useCallback(
    (index: number) => {
      setActiveIndex(index);
      setCurrentImageUrl(visibleImages[index]?.image || resolvedFallback);
    },
    [visibleImages, resolvedFallback]
  );

  const imageElement = settings.customRenderers.renderImage ? (
    settings.customRenderers.renderImage({
      src: currentImageUrl,
      alt,
      width,
      height,
      fill,
      sizes,
      aspectRatio
    })
  ) : (
    <Image
      src={currentImageUrl}
      alt={alt}
      {...(fill
        ? { fill: true, sizes: sizes!, aspectRatio: aspectRatio! }
        : { width: width!, height: height! })}
      className={settings.customStyles.image}
    />
  );

  return (
    <div
      className={twMerge(
        'relative',
        settings.customStyles.container,
        className
      )}
    >
      <div className={twMerge('relative', settings.customStyles.imageWrapper)}>
        {imageElement}
      </div>

      <HoverZones
        count={visibleImages.length}
        href={href}
        onHover={handleImageChange}
        customStyles={settings.customStyles}
      />

      <Indicators
        count={visibleImages.length}
        activeIndex={activeIndex}
        onSelect={handleImageChange}
        customStyles={settings.customStyles}
        customRenderers={settings.customRenderers}
      />
    </div>
  );
}
