import React, { useCallback, useEffect, useRef, useState } from 'react'
import axios from 'axios'
import CommentForm from '../comments/CommentForm'
import ReactionBar from '../comments/ReactionBar'
import { isFlood } from '../../utils/emojiFlood'

// ── Helpers ───────────────────────────────────────────────────────────────────

function timeAgo(dateStr) {
  if (!dateStr) return ''
  const date    = new Date(dateStr)
  const seconds = Math.floor((Date.now() - date.getTime()) / 1000)
  if (seconds < 60) return 'just now'
  const minutes = Math.floor(seconds / 60)
  if (minutes < 60) return `${minutes}m ago`
  const hours = Math.floor(minutes / 60)
  if (hours < 24) return `${hours}h ago`
  const days = Math.floor(hours / 24)
  if (days < 365) return `${days}d ago`
  return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
}

function Avatar({ user, size = 36 }) {
  if (user?.avatar_url) {
    return (
      <img
        src={user.avatar_url}
        alt={user.name || user.username || ''}
        width={size}
        height={size}
        className="rounded-full object-cover shrink-0"
        style={{ width: size, height: size }}
        loading="lazy"
        onError={(e) => {
          e.currentTarget.onerror = null
          e.currentTarget.src = 'https://files.skinbase.org/avatars/default.webp'
        }}
      />
    )
  }
  const initials = (user?.name || user?.username || '?').slice(0, 1).toUpperCase()
  return (
    <span
      className="flex items-center justify-center rounded-full bg-neutral-700 text-sm font-bold text-white shrink-0"
      style={{ width: size, height: size }}
    >
      {initials}
    </span>
  )
}

// ── Single comment ────────────────────────────────────────────────────────────

function CommentItem({ comment, isLoggedIn }) {
  const user      = comment.user
  const html      = comment.rendered_content ?? null
  const plain     = comment.content ?? ''

  // Emoji-flood collapse: long runs of repeated emoji get a show-more toggle.
  const flood             = isFlood(plain)
  const [expanded, setExpanded] = useState(!flood)

  // Build initial reaction totals (empty if not provided by server)
  const [reactionTotals, setReactionTotals] = useState(comment.reactions ?? {})

  // Load reactions lazily if not provided
  useEffect(() => {
    if (comment.reactions || !comment.id) return
    axios
      .get(`/api/comments/${comment.id}/reactions`)
      .then(({ data }) => setReactionTotals(data.totals ?? {}))
      .catch(() => {})
  }, [comment.id, comment.reactions])

  return (
    <li className="flex gap-3" id={`comment-${comment.id}`}>
      {/* Avatar */}
      {user?.profile_url ? (
        <a href={user.profile_url} className="shrink-0 mt-0.5" tabIndex={-1} aria-hidden="true">
          <Avatar user={user} size={36} />
        </a>
      ) : (
        <span className="shrink-0 mt-0.5">
          <Avatar user={user} size={36} />
        </span>
      )}

      {/* Content */}
      <div className="min-w-0 flex-1 space-y-1.5">
        {/* Header */}
        <div className="flex items-baseline gap-2 flex-wrap">
          {user?.profile_url ? (
            <a href={user.profile_url} className="text-sm font-medium text-white hover:underline">
              {user.display || user.username || user.name || 'Member'}
            </a>
          ) : (
            <span className="text-sm font-medium text-white">
              {user?.display || user?.username || user?.name || 'Member'}
            </span>
          )}
          <time
            dateTime={comment.created_at}
            title={comment.created_at ? new Date(comment.created_at).toLocaleString() : ''}
            className="text-xs text-neutral-500"
          >
            {comment.time_ago || timeAgo(comment.created_at)}
          </time>
        </div>

        {/* Body — use rendered_content (safe HTML) when available, else plain text */}
        {/* Flood-collapse wrapper: clips height when content is a repeated-emoji flood */}
        <div
          className={!expanded ? 'overflow-hidden relative' : undefined}
          style={!expanded ? { maxHeight: '5em' } : undefined}
        >
          {html ? (
            <div
              className="text-sm text-neutral-300 leading-relaxed prose prose-invert prose-sm max-w-none
                         prose-a:text-sky-400 prose-a:no-underline hover:prose-a:underline
                         prose-code:bg-white/[0.07] prose-code:px-1 prose-code:rounded prose-code:text-xs"
              // rendered_content is server-sanitized HTML — safe to inject
              dangerouslySetInnerHTML={{ __html: html }}
            />
          ) : (
            <p className="text-sm text-neutral-300 whitespace-pre-line break-words leading-relaxed">
              {plain}
            </p>
          )}

          {/* Gradient fade at the bottom while collapsed */}
          {flood && !expanded && (
            <div
              className="absolute inset-x-0 bottom-0 h-6 bg-gradient-to-t from-neutral-900 to-transparent pointer-events-none"
              aria-hidden="true"
            />
          )}
        </div>

        {/* Flood expand / collapse toggle */}
        {flood && (
          <button
            type="button"
            onClick={() => setExpanded((e) => !e)}
            className="text-xs text-sky-400 hover:text-sky-300 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-sky-500 rounded"
            aria-expanded={expanded}
          >
            {expanded ? '▲\u2009Collapse' : '▼\u2009Show full comment'}
          </button>
        )}

        {/* Reactions */}
        {Object.keys(reactionTotals).length > 0 && (
          <ReactionBar
            entityType="comment"
            entityId={comment.id}
            initialTotals={reactionTotals}
            isLoggedIn={isLoggedIn}
          />
        )}
      </div>
    </li>
  )
}

// ── Skeleton ──────────────────────────────────────────────────────────────────

function Skeleton() {
  return (
    <div className="space-y-4 animate-pulse">
      {Array.from({ length: 3 }).map((_, i) => (
        <div key={i} className="flex gap-3">
          <div className="w-9 h-9 rounded-full bg-white/[0.07] shrink-0" />
          <div className="flex-1 space-y-2 pt-1">
            <div className="h-3 bg-white/[0.07] rounded w-28" />
            <div className="h-3 bg-white/[0.05] rounded w-full" />
            <div className="h-3 bg-white/[0.04] rounded w-2/3" />
          </div>
        </div>
      ))}
    </div>
  )
}

// ── Main export ───────────────────────────────────────────────────────────────

/**
 * ArtworkComments
 *
 * Can operate in two modes:
 *  1. Static: pass `comments` array from Inertia page props (legacy / SSR)
 *  2. Dynamic: pass `artworkId` to load + post comments via the API
 *
 * Props:
 *   artworkId    number              Used for API calls
 *   comments     array               SSR initial comments (optional)
 *   isLoggedIn   boolean
 *   loginUrl     string
 */
export default function ArtworkComments({
  artworkId,
  comments: initialComments = [],
  isLoggedIn = false,
  loginUrl = '/login',
}) {
  const [comments, setComments]   = useState(initialComments)
  const [loading, setLoading]     = useState(false)
  const [page, setPage]           = useState(1)
  const [lastPage, setLastPage]   = useState(1)
  const [total, setTotal]         = useState(initialComments.length)
  const initialized               = useRef(false)

  // Load comments from API
  const loadComments = useCallback(
    async (p = 1) => {
      if (!artworkId) return
      setLoading(true)
      try {
        const { data } = await axios.get(`/api/artworks/${artworkId}/comments?page=${p}`)
        if (p === 1) {
          setComments(data.data ?? [])
        } else {
          setComments((prev) => [...prev, ...(data.data ?? [])])
        }
        setPage(data.meta?.current_page ?? p)
        setLastPage(data.meta?.last_page ?? 1)
        setTotal(data.meta?.total ?? 0)
      } catch {
        // keep existing data on error
      } finally {
        setLoading(false)
      }
    },
    [artworkId],
  )

  // On mount, load if artworkId provided and no SSR comments given
  useEffect(() => {
    if (initialized.current) return
    initialized.current = true

    if (artworkId && initialComments.length === 0) {
      loadComments(1)
    } else {
      setTotal(initialComments.length)
    }
  }, [artworkId, initialComments.length, loadComments])

  const handlePosted = useCallback((newComment) => {
    setComments((prev) => [newComment, ...prev])
    setTotal((t) => t + 1)
  }, [])

  return (
    <section aria-label="Comments" className="space-y-6">
      <h2 className="text-base font-semibold text-white">
        Comments{' '}
        {total > 0 && (
          <span className="text-neutral-500 font-normal">({total})</span>
        )}
      </h2>

      {/* Comment form */}
      {artworkId && (
        <CommentForm
          artworkId={artworkId}
          onPosted={handlePosted}
          isLoggedIn={isLoggedIn}
          loginUrl={loginUrl}
        />
      )}

      {/* Comment list */}
      {loading && comments.length === 0 ? (
        <Skeleton />
      ) : comments.length === 0 ? (
        <p className="text-sm text-neutral-500">No comments yet. Be the first!</p>
      ) : (
        <>
          <ul className="space-y-5">
            {comments.map((comment) => (
              <CommentItem
                key={comment.id}
                comment={comment}
                isLoggedIn={isLoggedIn}
              />
            ))}
          </ul>

          {/* Load more */}
          {page < lastPage && (
            <div className="flex justify-center pt-2">
              <button
                type="button"
                disabled={loading}
                onClick={() => loadComments(page + 1)}
                className="px-5 py-2 rounded-lg text-sm text-white/60 border border-white/[0.08] hover:text-white hover:border-white/20 transition-colors disabled:opacity-40"
              >
                {loading ? 'Loading…' : 'Load more comments'}
              </button>
            </div>
          )}
        </>
      )}
    </section>
  )
}

