import React, { useEffect, useMemo, useState } from 'react'
import ArtworkCard from './ArtworkCard'

function getCsrfToken() {
  if (typeof document === 'undefined') return ''
  return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
}

async function revokeDismissSignal(entry) {
  const item = entry?.item || null
  const kind = entry?.kind || null

  if (!item || !kind) {
    throw new Error('missing_dismiss_entry')
  }

  const endpoint = kind === 'dislike-tag'
    ? item.dislike_tag_endpoint || item?.negative_feedback?.dislike_tag_endpoint
    : item.hide_artwork_endpoint || item?.negative_feedback?.hide_artwork_endpoint

  if (!endpoint) {
    throw new Error('missing_revoke_endpoint')
  }

  const payload = kind === 'dislike-tag'
    ? {
        tag_id: item?.primary_tag?.id ? Number(item.primary_tag.id) : undefined,
        tag_slug: item?.primary_tag?.slug || item?.primary_tag?.name || undefined,
        artwork_id: Number(item.id),
        algo_version: item?.recommendation_algo_version || item?.algo_version || undefined,
        meta: {
          gallery_type: item?.recommendation_surface || item?.gallery_type || 'recommendation-surface',
          reason: item?.recommendation_reason || null,
          interaction_origin: 'artwork-gallery-undo-dislike-tag',
        },
      }
    : {
        artwork_id: Number(item.id),
        algo_version: item?.recommendation_algo_version || item?.algo_version || undefined,
        meta: {
          gallery_type: item?.recommendation_surface || item?.gallery_type || 'recommendation-surface',
          reason: item?.recommendation_reason || null,
          interaction_origin: 'artwork-gallery-undo-hide',
        },
      }

  const response = await fetch(endpoint, {
    method: 'DELETE',
    credentials: 'same-origin',
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-TOKEN': getCsrfToken(),
      'X-Requested-With': 'XMLHttpRequest',
    },
    body: JSON.stringify(payload),
  })

  if (!response.ok) {
    throw new Error('revoke_request_failed')
  }

  return response.json().catch(() => null)
}

function cx(...parts) {
  return parts.filter(Boolean).join(' ')
}

function getArtworkKey(item, index) {
  if (item?.id) return item.id
  if (item?.title || item?.name || item?.author) {
    return `${item.title || item.name || 'artwork'}-${item.author || item.author_name || item.uname || 'artist'}-${index}`
  }

  return `artwork-${index}`
}

function DismissNotice({ notice, onUndo, onClose }) {
  if (!notice) return null

  return (
    <div className="pointer-events-none fixed bottom-5 right-5 z-50 max-w-sm" aria-live="polite" aria-atomic="true">
      <div className="pointer-events-auto rounded-2xl border border-amber-300/30 bg-slate-950/92 px-4 py-3 text-amber-50 shadow-2xl shadow-black/40 backdrop-blur">
        <p className="text-[11px] uppercase tracking-[0.2em] text-amber-100/70">Discovery Feedback</p>
        <p className="mt-1 text-sm font-medium">{notice.message}</p>
        <div className="mt-3 flex items-center gap-2">
          <button
            type="button"
            onClick={onUndo}
            disabled={notice.busy}
            className="inline-flex items-center rounded-full border border-white/15 px-3 py-1 text-xs font-semibold uppercase tracking-[0.14em] text-white/85 transition hover:border-white/30 hover:text-white"
          >
            {notice.busy ? 'Undoing...' : 'Undo'}
          </button>
          <button
            type="button"
            onClick={onClose}
            className="inline-flex items-center rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-[0.14em] text-white/55 transition hover:text-white/85"
          >
            Dismiss
          </button>
        </div>
      </div>
    </div>
  )
}

export default function ArtworkGallery({
  items,
  layout = 'grid',
  compact = false,
  showStats = true,
  showAuthor = true,
  className = '',
  cardClassName = '',
  limit,
  containerProps = {},
  resolveCardProps,
  children,
}) {
  if (!Array.isArray(items) || items.length === 0) return null

  const visibleItems = typeof limit === 'number' ? items.slice(0, limit) : items
  const [dismissedEntries, setDismissedEntries] = useState([])
  const [dismissNotice, setDismissNotice] = useState(null)
  const visibleArtworkItems = useMemo(
    () => visibleItems.filter((item) => !item?.maturity?.should_hide && !dismissedEntries.some((entry) => entry.item?.id === item?.id)),
    [dismissedEntries, visibleItems]
  )
  const baseClassName = layout === 'masonry'
    ? 'grid gap-6'
    : 'grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5'

  useEffect(() => {
    if (!dismissNotice) {
      return undefined
    }

    const timeoutId = window.setTimeout(() => {
      setDismissNotice(null)
    }, 3200)

    return () => {
      window.clearTimeout(timeoutId)
    }
  }, [dismissNotice])

  function handleDismissed(item, kind) {
    if (!item?.id) return

    setDismissedEntries((current) => {
      const next = current.filter((entry) => entry.item?.id !== item.id)
      next.push({ item, kind })
      return next
    })

    setDismissNotice({
      itemId: item.id,
      busy: false,
      message: kind === 'dislike-tag'
        ? `We will show less content like #${item?.primary_tag?.slug || item?.primary_tag?.name || 'this tag'}.`
        : 'Artwork hidden from this recommendation view.',
    })
  }

  async function handleUndoDismiss() {
    if (!dismissNotice?.itemId) {
      setDismissNotice(null)
      return
    }

    const entry = dismissedEntries.find((current) => current.item?.id === dismissNotice.itemId)
    if (!entry) {
      setDismissNotice(null)
      return
    }

    setDismissNotice((current) => current ? { ...current, busy: true } : current)

    try {
      await revokeDismissSignal(entry)
    } catch {
      setDismissNotice({
        itemId: entry.item.id,
        busy: false,
        message: 'Undo failed. The feedback signal is still active.',
      })
      return
    }

    setDismissedEntries((current) => current.filter((entry) => entry.item?.id !== dismissNotice.itemId))
    setDismissNotice(null)
  }

  return (
    <>
      <div className={cx(baseClassName, className)} {...containerProps}>
      {visibleArtworkItems.map((item, index) => {
        const cardProps = resolveCardProps?.(item, index) || {}
        const { className: resolvedClassName = '', ...restCardProps } = cardProps

        return (
          <ArtworkCard
            key={getArtworkKey(item, index)}
            artwork={item}
            compact={compact}
            showStats={showStats}
            showAuthor={showAuthor}
            className={cx(cardClassName, resolvedClassName)}
            onDismissed={handleDismissed}
            {...restCardProps}
          />
        )
      })}
      {children}
      </div>
      <DismissNotice notice={dismissNotice} onUndo={handleUndoDismiss} onClose={() => setDismissNotice(null)} />
    </>
  )
}
