'use client';

import React, { useMemo, useState } from 'react';

import Image from 'next/image';

import { cn } from '@/lib/utils';
import {
  getCreationCreatorDisplayName,
  getCreationDateLabel,
  getCreationHref,
} from '@/utils/creationHelpers';
import { buildMediaUrl } from '@/utils/images';

import type { CreationListItem } from '@/types/Creation';

import { Link } from '@/i18n/navigation';

const DEFAULT_IMAGE_RATIO = 4 / 3;

type CreationCarouselImage = {
  src: string;
  alt: string;
  width?: number | null;
  height?: number | null;
};

export type CreationCarouselItem = {
  id: string;
  title: string;
  href?: ReturnType<typeof getCreationHref>;
  image?: CreationCarouselImage;
  meta?: string | null;
  creators?: string | null;
};

interface CreationCarouselCardProps {
  item: CreationCarouselItem;
  className?: string;
}

const normalizeDisplayText = (value?: string | null) =>
  (value ?? '')
    .replaceAll('|', ', ')
    .replaceAll(' ,', ',')
    .replaceAll('&nbsp;', ' ')
    .replaceAll('<0xa0>', ' ')
    .trim();

const isPositiveNumber = (value: unknown): value is number =>
  typeof value === 'number' && Number.isFinite(value) && value > 0;

const getImageRatio = (image?: CreationCarouselImage) => {
  if (image && isPositiveNumber(image.width) && isPositiveNumber(image.height)) {
    return image.width / image.height;
  }

  return DEFAULT_IMAGE_RATIO;
};

const getCreationCarouselImage = (
  creation: CreationListItem,
  title: string
): CreationCarouselImage | undefined => {
  if (creation.fokepId) {
    return {
      src: buildMediaUrl(creation.fokepId, 'h256'),
      alt: title,
    };
  }

  return undefined;
};

export const mapCreationToCarouselItem = (creation: CreationListItem): CreationCarouselItem => {
  const title = normalizeDisplayText(creation.nev) || normalizeDisplayText(creation.label) || '-';
  const creators = normalizeDisplayText(getCreationCreatorDisplayName(creation));

  return {
    id: creation.alkotasAzonosito || String(creation.id || title),
    title,
    href: getCreationHref(creation) || undefined,
    image: getCreationCarouselImage(creation, title),
    meta: normalizeDisplayText(getCreationDateLabel(creation)),
    creators,
  };
};

const isExternalHref = (href: CreationCarouselItem['href']): href is string =>
  typeof href === 'string' && /^(https?:|mailto:|tel:)/.test(href);

const CreationCarouselCard: React.FC<CreationCarouselCardProps> = ({ item, className }) => {
  const [loadedImageRatio, setLoadedImageRatio] = useState<number | null>(null);
  const [imageFailed, setImageFailed] = useState(false);
  const imageRatio = loadedImageRatio ?? getImageRatio(item.image);
  // the upstream image endpoint can 500 intermittently under burst load —
  // degrade to the title placeholder instead of showing a broken image.
  const showImage = Boolean(item.image) && !imageFailed;
  const hasHref = Boolean(item.href);
  const cardStyle = useMemo(
    () =>
      ({
        '--creation-carousel-card-ratio': String(imageRatio),
        width:
          'calc(var(--creation-carousel-image-height, 260px) * var(--creation-carousel-card-ratio))',
      }) as React.CSSProperties,
    [imageRatio]
  );

  const content = (
    <>
      <div className="relative h-[var(--creation-carousel-image-height)] w-full overflow-hidden bg-[#eef3f6]">
        {showImage && item.image ? (
          <Image
            src={item.image.src}
            alt={item.image.alt}
            fill
            sizes="(max-width: 640px) 75vw, (max-width: 1024px) 380px, 430px"
            className="object-contain transition-transform duration-500 group-hover:scale-[1.015]"
            onLoad={(event) => {
              const image = event.currentTarget;
              if (image.naturalWidth > 0 && image.naturalHeight > 0) {
                setLoadedImageRatio(image.naturalWidth / image.naturalHeight);
              }
            }}
            onError={() => setImageFailed(true)}
          />
        ) : (
          <div className="flex h-full w-full items-center justify-center px-6 text-center text-xs font-semibold uppercase tracking-m text-[#151720]/45">
            {item.title}
          </div>
        )}
      </div>

      <div className="flex min-h-[112px] flex-col gap-1.5 pt-3">
        {item.meta && (
          <div className="ui-meta line-clamp-1 text-[11px] leading-[1.05] text-[#151720]/70">
            {item.meta}
          </div>
        )}
        <h3 className="line-clamp-2 text-[15px] font-semibold leading-tight text-[#151720]">
          {item.title}
        </h3>
        {item.creators && (
          <div className="line-clamp-1 text-[11px] font-semibold uppercase leading-[1.2] tracking-[0.07em] text-[#151720]/65">
            {item.creators}
          </div>
        )}
      </div>
    </>
  );

  const baseClassName = cn(
    'group block h-full overflow-hidden rounded-[2px] bg-transparent transition-colors duration-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-mma-blue focus-visible:ring-offset-2',
    hasHref && 'hover:text-mma-blue',
    className
  );

  if (item.href && isExternalHref(item.href)) {
    return (
      <a
        href={item.href}
        target="_blank"
        rel="noopener noreferrer"
        className={baseClassName}
        style={cardStyle}
      >
        {content}
      </a>
    );
  }

  if (item.href) {
    return (
      <Link href={item.href as never} className={baseClassName} style={cardStyle}>
        {content}
      </Link>
    );
  }

  return (
    <article className={baseClassName} style={cardStyle}>
      {content}
    </article>
  );
};

export default CreationCarouselCard;
