import React, { useEffect, useRef } from 'react';

function slugify(str) {
  return (str || '').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
}

/**
 * React version of resources/views/components/artwork-card.blade.php
 * Keeps identical HTML structure so existing CSS (nova-card, nova-card-media, etc.) applies.
 */
export default function ArtworkCard({ art, loading = 'lazy', fetchpriority = null }) {
  const imgRef   = useRef(null);
  const mediaRef = useRef(null);

  const title    = (art.name || art.title || 'Untitled artwork').trim();
  const author   = (art.uname || art.author_name || art.author || 'Skinbase').trim();
  const username = (art.username || art.uname || '').trim();
  const category = (art.category_name || art.category || '').trim();

  const likes    = art.likes ?? art.favourites ?? 0;
  const comments = art.comments_count ?? art.comment_count ?? 0;

  const imgSrc    = art.thumb    || art.thumb_url    || art.thumbnail_url    || '/images/placeholder.jpg';
  const imgSrcset = art.thumb_srcset || imgSrc;

  const cardUrl  = art.url || (art.id ? `/art/${art.id}/${slugify(title)}` : '#');
  const authorUrl = username ? `/@${username.toLowerCase()}` : null;
  // Use pre-computed CDN URL from the server; JS fallback mirrors AvatarUrl::default()
  const cdnBase = 'https://files.skinbase.org';
  const avatarSrc = art.avatar_url || `${cdnBase}/avatars/default.webp`;

  const hasDimensions = Number(art.width) > 0 && Number(art.height) > 0;
  const aspectRatio   = hasDimensions ? Number(art.width) / Number(art.height) : null;

  // Activate blur-preview class once image has decoded (mirrors nova.js behaviour).
  // If the server didn't supply dimensions (old artworks with width=0/height=0),
  // read naturalWidth/naturalHeight from the loaded image and imperatively set
  // the container's aspect-ratio so the masonry ResizeObserver picks up real proportions.
  useEffect(() => {
    const img   = imgRef.current;
    const media = mediaRef.current;
    if (!img) return;

    const markLoaded = () => {
      img.classList.add('is-loaded');
      // If no server-side dimensions, apply real ratio from the decoded image
      if (media && !hasDimensions && img.naturalWidth > 0 && img.naturalHeight > 0) {
        media.style.aspectRatio = `${img.naturalWidth} / ${img.naturalHeight}`;
      }
    };

    if (img.complete && img.naturalWidth > 0) { markLoaded(); return; }
    img.addEventListener('load',  markLoaded, { once: true });
    img.addEventListener('error', markLoaded, { once: true });
  }, []);

  // Span 2 columns for panoramic images (AR > 2.0) in Photography or Wallpapers categories.
  // These slugs match the root categories; name-matching is kept as fallback.
  const wideCategories = ['photography', 'wallpapers', 'photography-digital', 'wallpaper'];
  const wideCategoryNames = ['photography', 'wallpapers'];
  const catSlug = (art.category_slug || '').toLowerCase();
  const catName = (art.category_name || '').toLowerCase();
  const isWideEligible =
    aspectRatio !== null &&
    aspectRatio > 2.0 &&
    (wideCategories.includes(catSlug) || wideCategoryNames.includes(catName));

  const articleStyle = isWideEligible ? { gridColumn: 'span 2' } : {};
  const aspectStyle  = hasDimensions ? { aspectRatio: `${art.width} / ${art.height}` } : {};
  // Image always fills the container absolutely – the container's height is
  // driven by aspect-ratio (capped by CSS max-height). Using absolute
  // positioning means width/height are always 100% of the capped box, so
  // object-cover crops top/bottom instead of leaving dark gaps.
  const imgClass = [
    'nova-card-main-image',
    'absolute inset-0 h-full w-full object-cover',
    'transition-[transform,filter] duration-300 ease-out group-hover:scale-[1.04]',
    loading !== 'eager' ? 'blur-sm scale-[1.02] data-blur-preview' : '',
  ].join(' ');

  const metaParts = [];
  if (art.resolution) metaParts.push(art.resolution);
  else if (hasDimensions) metaParts.push(`${art.width}×${art.height}`);
  if (category) metaParts.push(category);
  if (art.license) metaParts.push(art.license);

  return (
    <article
      className={`nova-card gallery-item artwork relative${isWideEligible ? ' nova-card--wide' : ''}`}
      style={articleStyle}
      data-art-id={art.id}
      data-art-url={cardUrl}
      data-art-title={title}
      data-art-img={imgSrc}
    >
      <a
        href={cardUrl}
        className="group relative block overflow-hidden rounded-2xl ring-1 ring-white/5 bg-black/20
          shadow-lg shadow-black/40
          transition-all duration-300 ease-out
          hover:scale-[1.02] hover:-translate-y-px hover:ring-white/15
          hover:shadow-[0_8px_30px_rgba(0,0,0,0.6),0_0_0_1px_rgba(255,255,255,0.08)]
          focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-300/70"
        style={{ willChange: 'transform' }}
      >
        {/* nova-card-media: height driven by aspect-ratio, capped by MasonryGallery.css max-height.
             w-full prevents browsers shrinking the width when max-height overrides aspect-ratio. */}
        <div
          ref={mediaRef}
          className="nova-card-media relative w-full overflow-hidden bg-neutral-900"
          style={aspectStyle}
        >
          <div className="absolute inset-0 bg-gradient-to-br from-white/10 via-white/5 to-transparent pointer-events-none" />

          <img
            ref={imgRef}
            src={imgSrc}
            srcSet={imgSrcset}
            sizes="(max-width: 768px) 50vw, (max-width: 1280px) 33vw, 20vw"
            loading={loading}
            decoding={loading === 'eager' ? 'sync' : 'async'}
            fetchPriority={fetchpriority || undefined}
            alt={title}
            width={hasDimensions ? art.width  : undefined}
            height={hasDimensions ? art.height : undefined}
            className={imgClass}
            data-blur-preview={loading !== 'eager' ? '' : undefined}
          />

          {/* Overlay caption */}
          <div className="pointer-events-none absolute inset-x-0 bottom-0 z-20 bg-gradient-to-t from-black/80 via-black/40 to-transparent p-3 backdrop-blur-[2px] opacity-100 transition-opacity duration-200 md:opacity-0 md:group-hover:opacity-100 md:group-focus-visible:opacity-100">
            <div className="truncate text-sm font-semibold text-white">{title}</div>
            <div className="mt-1 flex items-center justify-between gap-3 text-xs text-white/80">
              <span className="truncate flex items-center gap-2">
                <img
                  src={avatarSrc}
                  alt={`Avatar of ${author}`}
                  className="w-6 h-6 shrink-0 rounded-full object-cover"
                  loading="lazy"
                />
                <span className="truncate">
                  <span>{author}</span>
                  {username && (
                    <span className="text-white/60"> @{username}</span>
                  )}
                </span>
              </span>
              <span className="shrink-0">❤ {likes} · 💬 {comments}</span>
            </div>
            {metaParts.length > 0 && (
              <div className="mt-1 text-[11px] text-white/70">
                {metaParts.join(' • ')}
              </div>
            )}
          </div>
        </div>

        <span className="sr-only">{title} by {author}</span>
      </a>

      {/* ── Quick actions: top-right, shown on card hover via CSS ─────── */}
      <div className="nb-card-actions" aria-hidden="true">
        <button
          type="button"
          className="nb-card-action-btn"
          title="Favourite"
          tabIndex={-1}
          onClick={(e) => {
            e.preventDefault();
            e.stopPropagation();
            // Favourite action – wired to API in future iteration
          }}
        >
          ♥
        </button>
        <a
          href={`${cardUrl}?download=1`}
          className="nb-card-action-btn"
          title="Download"
          tabIndex={-1}
          onClick={(e) => e.stopPropagation()}
        >
          ⬇
        </a>
        <a
          href={cardUrl}
          className="nb-card-action-btn"
          title="Quick view"
          tabIndex={-1}
        >
          👁
        </a>
      </div>

    </article>
  );
}
