import React, { useEffect, useMemo, useState } from 'react'
import ArchiveScreenshotPicker from '../ArchiveScreenshotPicker'
import UploadSidebar from '../UploadSidebar'
import { getContentTypeValue, getContentTypeVisualKey } from '../../../lib/uploadUtils'

/**
 * Step2Details
 *
 * Step 2 of the upload wizard: artwork metadata.
 * Shows uploaded-asset summary, content type selector,
 * category/subcategory selectors, tags, description, and rights.
 */
export default function Step2Details({
  headingRef,
  // Asset summary
  primaryFile,
  primaryPreviewUrl,
  isArchive,
  fileMetadata,
  screenshots,
  selectedScreenshotIndex,
  onSelectedScreenshotChange,
  // Content type + category
  contentTypes,
  metadata,
  metadataErrors,
  filteredCategoryTree,
  allRootCategoryOptions,
  requiresSubCategory,
  onContentTypeChange,
  onRootCategoryChange,
  onSubCategoryChange,
  groupOptions,
  currentContributorOptions,
  onGroupChange,
  onPrimaryAuthorChange,
  onContributorToggle,
  onContributorRoleChange,
  onContributorPrimaryChange,
  // Sidebar (title / tags / description / rights)
  suggestedTags,
  publishMode,
  scheduledAt,
  timezone,
  onPublishModeChange,
  onScheduleAt,
  onChangeTitle,
  onChangeTags,
  onChangeDescription,
  onToggleMature,
  onToggleRights,
}) {
  const [isContentTypeChooserOpen, setIsContentTypeChooserOpen] = useState(() => !metadata.contentType)
  const [isCategoryChooserOpen, setIsCategoryChooserOpen] = useState(() => !metadata.rootCategoryId)
  const [isSubCategoryChooserOpen, setIsSubCategoryChooserOpen] = useState(() => !metadata.subCategoryId)
  const [categorySearch, setCategorySearch] = useState('')
  const [subCategorySearch, setSubCategorySearch] = useState('')

  const contentTypeOptions = useMemo(
    () => (Array.isArray(contentTypes) ? contentTypes : []).map((item) => {
      const normalizedName = String(item?.name || '').trim().toLowerCase()
      const normalizedSlug = String(item?.slug || '').trim().toLowerCase()

      if (normalizedName === 'other' || normalizedSlug === 'other') {
        return {
          ...item,
          name: 'Others',
        }
      }

      return item
    }),
    [contentTypes]
  )

  const selectedContentType = useMemo(
    () => contentTypeOptions.find((item) => String(getContentTypeValue(item)) === String(metadata.contentType || '')) ?? null,
    [contentTypeOptions, metadata.contentType]
  )

  const selectedRoot = useMemo(
    () => filteredCategoryTree.find((item) => String(item.id) === String(metadata.rootCategoryId || '')) ?? null,
    [filteredCategoryTree, metadata.rootCategoryId]
  )

  const subCategories = selectedRoot?.children || []
  const selectedSubCategory = useMemo(
    () => subCategories.find((item) => String(item.id) === String(metadata.subCategoryId || '')) ?? null,
    [subCategories, metadata.subCategoryId]
  )

  const sortedFilteredCategories = useMemo(() => {
    const sorted = [...filteredCategoryTree].sort((a, b) => a.name.localeCompare(b.name))
    const q = categorySearch.trim().toLowerCase()
    return q ? sorted.filter((c) => c.name.toLowerCase().includes(q)) : sorted
  }, [filteredCategoryTree, categorySearch])

  const sortedFilteredSubCategories = useMemo(() => {
    const sorted = [...subCategories].sort((a, b) => a.name.localeCompare(b.name))
    const q = subCategorySearch.trim().toLowerCase()
    return q ? sorted.filter((s) => s.name.toLowerCase().includes(q)) : sorted
  }, [subCategories, subCategorySearch])
  const contributorCredits = metadata.contributorCredits || {}

  useEffect(() => {
    if (!metadata.contentType) {
      setIsContentTypeChooserOpen(true)
    }
  }, [metadata.contentType])

  useEffect(() => {
    if (!metadata.rootCategoryId) {
      setIsCategoryChooserOpen(true)
    }
  }, [metadata.rootCategoryId])

  useEffect(() => {
    if (!metadata.subCategoryId) {
      setIsSubCategoryChooserOpen(true)
    }
  }, [metadata.subCategoryId])

  return (
    <div className="space-y-5 rounded-[28px] border border-white/10 bg-[linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02))] p-6 shadow-[0_24px_90px_rgba(2,8,23,0.28)] backdrop-blur sm:p-7">
      {/* Step header */}
      <div className="rounded-2xl border border-white/8 bg-white/[0.04] px-5 py-4">
        <h2
          ref={headingRef}
          tabIndex={-1}
          className="text-lg font-semibold text-white focus:outline-none"
        >
          Artwork details
        </h2>
        <p className="mt-1 text-sm text-white/60">
          Complete required metadata and rights confirmation before publishing.
        </p>
      </div>

      {/* Uploaded asset summary */}
      <div className="rounded-2xl ring-1 ring-white/8 bg-white/[0.025] p-5">
        <p className="mb-3 text-[11px] uppercase tracking-wide text-white/45">Uploaded asset</p>
        <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
          {/* Thumbnail / Archive icon */}
          {primaryPreviewUrl && !isArchive ? (
            <div className="flex h-[120px] w-[120px] items-center justify-center overflow-hidden rounded-xl ring-1 ring-white/10 bg-black/30 shrink-0">
              <img
                src={primaryPreviewUrl}
                alt="Uploaded artwork thumbnail"
                className="max-h-full max-w-full object-contain"
                loading="lazy"
                decoding="async"
                width={120}
                height={120}
              />
            </div>
          ) : (
            <div className="grid h-[120px] w-[120px] place-items-center rounded-xl ring-1 ring-white/10 bg-white/5 shrink-0">
              <svg className="h-8 w-8 text-white/30" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" aria-hidden="true">
                <path strokeLinecap="round" strokeLinejoin="round" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
              </svg>
            </div>
          )}

          {/* File metadata */}
          <div className="min-w-0 space-y-1">
            <p className="truncate text-sm font-medium text-white">
              {primaryFile?.name || 'Primary file'}
            </p>
            <p className="text-xs text-white/50">
              {isArchive
                ? `Archive · ${screenshots.length} screenshot${screenshots.length !== 1 ? 's' : ''}`
                : fileMetadata.resolution !== '—'
                  ? `${fileMetadata.resolution} · ${fileMetadata.size}`
                  : fileMetadata.size}
            </p>
            <span className={`inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] ${isArchive ? 'border-amber-400/40 bg-amber-400/10 text-amber-200' : 'border-sky-400/40 bg-sky-400/10 text-sky-200'}`}>
              {isArchive ? 'Archive' : 'Image'}
            </span>
          </div>
        </div>

        {isArchive && screenshots.length > 0 && (
          <div className="mt-5 border-t border-white/8 pt-5">
            <ArchiveScreenshotPicker
              screenshots={screenshots}
              selectedIndex={selectedScreenshotIndex}
              onSelect={onSelectedScreenshotChange}
              title="Archive screenshots"
              description="All selected screenshots are shown here. Pick the one that should become the main preview thumbnail."
            />
          </div>
        )}
      </div>

      {/* ── Combined: Content type → Category → Subcategory ─────────────────── */}
      <section className="rounded-2xl border border-white/10 bg-[radial-gradient(ellipse_at_top_left,_rgba(14,165,233,0.07),_transparent_45%),radial-gradient(ellipse_at_bottom_right,_rgba(168,85,247,0.07),_transparent_45%)] p-5 sm:p-6">
        {/* Section header */}
        <div className="mb-5 flex flex-wrap items-start justify-between gap-2">
          <div>
            <h3 className="text-sm font-semibold text-white">Content type &amp; category</h3>
            <p className="mt-1 text-xs text-white/55">Choose the content family, then narrow down to a category and subcategory.</p>
          </div>
          <span className="rounded-full border border-sky-400/30 bg-sky-400/10 px-2.5 py-0.5 text-[11px] uppercase tracking-widest text-sky-300">Step 2</span>
        </div>

        {/* ── Content type ── */}
        <div>
          <p className="mb-3 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Content type</p>

          {contentTypeOptions.length === 0 && (
            <div className="rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-4 text-sm text-slate-400">
              No content types are available right now.
            </div>
          )}

          {selectedContentType && !isContentTypeChooserOpen && (
            <div className="rounded-2xl border border-emerald-400/25 bg-emerald-400/[0.08] p-4">
              <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <div className="flex items-center gap-3">
                  <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border border-emerald-400/30 bg-emerald-400/10">
                    <img
                      src={`/gfx/mascot_${getContentTypeVisualKey(selectedContentType)}.webp`}
                      alt=""
                      className="h-7 w-7 object-contain"
                      onError={(e) => { e.currentTarget.style.display = 'none' }}
                    />
                  </div>
                  <div>
                    <div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-emerald-200/70">Selected</div>
                    <div className="mt-0.5 text-base font-semibold text-white">{selectedContentType.name}</div>
                  </div>
                </div>
                <button
                  type="button"
                  onClick={() => setIsContentTypeChooserOpen(true)}
                  className="inline-flex items-center justify-center rounded-xl border border-white/10 bg-white/[0.05] px-3 py-2 text-sm font-medium text-slate-200 transition hover:border-white/20 hover:bg-white/[0.08] hover:text-white"
                >
                  Change
                </button>
              </div>
            </div>
          )}

          {(!selectedContentType || isContentTypeChooserOpen) && (
            <div className="grid gap-3 lg:grid-cols-2">
              {contentTypeOptions.map((ct) => {
                const typeValue = String(getContentTypeValue(ct))
                const isActive = typeValue === String(metadata.contentType || '')
                const visualKey = getContentTypeVisualKey(ct)
                const categoryCount = Array.isArray(ct.categories) ? ct.categories.length : 0
                return (
                  <button
                    key={typeValue || ct.name}
                    type="button"
                    onClick={() => {
                      setIsContentTypeChooserOpen(false)
                      setIsCategoryChooserOpen(true)
                      onContentTypeChange(typeValue)
                    }}
                    className={[
                      'group flex w-full items-center gap-3 rounded-2xl border px-3 py-3 text-left transition-all',
                      isActive
                        ? 'border-emerald-400/40 bg-emerald-400/10 shadow-[0_0_0_1px_rgba(52,211,153,0.18)]'
                        : 'border-white/10 bg-white/[0.03] hover:border-white/20 hover:bg-white/[0.06]',
                    ].join(' ')}
                    aria-pressed={isActive}
                  >
                    <div className={`flex h-12 w-12 items-center justify-center rounded-2xl border ${isActive ? 'border-emerald-400/30 bg-emerald-400/10' : 'border-white/10 bg-white/[0.04]'}`}>
                      <img
                        src={`/gfx/mascot_${visualKey}.webp`}
                        alt=""
                        className="h-8 w-8 object-contain"
                        onError={(e) => { e.currentTarget.style.display = 'none' }}
                      />
                    </div>
                    <div className="min-w-0 flex-1">
                      <div className={`text-sm font-semibold ${isActive ? 'text-emerald-200' : 'text-white'}`}>{ct.name}</div>
                      <div className="mt-1 text-[11px] text-slate-500">{categoryCount} {categoryCount === 1 ? 'category' : 'categories'}</div>
                    </div>
                    <div className={`text-xs ${isActive ? 'text-emerald-300' : 'text-slate-500 group-hover:text-slate-300'}`}>
                      {isActive ? 'Selected' : 'Open'}
                    </div>
                  </button>
                )
              })}
            </div>
          )}

          {metadataErrors.contentType && <p className="mt-3 text-xs text-red-300">{metadataErrors.contentType}</p>}
        </div>

        {/* ── Category ── */}
        {selectedContentType && (
          <>
            <div className="my-5 border-t border-white/8" />
            <div>
              <div className="mb-3 flex items-center justify-between gap-2">
                <p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Category</p>
                <span className="text-[11px] text-slate-600">{filteredCategoryTree.length} available</span>
              </div>

              {selectedRoot && !isCategoryChooserOpen && (
                <div className="rounded-2xl border border-purple-400/25 bg-purple-400/[0.07] p-4">
                  <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                    <div>
                      <div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-purple-200/70">Selected</div>
                      <div className="mt-0.5 text-base font-semibold text-white">{selectedRoot.name}</div>
                      <div className="mt-1 text-xs text-slate-500">
                        {subCategories.length > 0
                          ? `${subCategories.length} subcategories available`
                          : 'No subcategory required'}
                      </div>
                    </div>
                    <button
                      type="button"
                      onClick={() => { setCategorySearch(''); setIsCategoryChooserOpen(true) }}
                      className="inline-flex items-center justify-center rounded-xl border border-white/10 bg-white/[0.05] px-3 py-2 text-sm font-medium text-slate-200 transition hover:border-white/20 hover:bg-white/[0.08] hover:text-white"
                    >
                      Change
                    </button>
                  </div>
                </div>
              )}

              {(!selectedRoot || isCategoryChooserOpen) && (
                <div className="space-y-3">
                  <div className="relative">
                    <svg className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fillRule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clipRule="evenodd" /></svg>
                    <input
                      type="search"
                      value={categorySearch}
                      onChange={(e) => setCategorySearch(e.target.value)}
                      placeholder="Search categories…"
                      className="w-full rounded-xl border border-white/10 bg-white/[0.04] py-2.5 pl-9 pr-4 text-sm text-white placeholder:text-slate-500 focus:border-purple-400/40 focus:outline-none focus:ring-1 focus:ring-purple-400/30"
                    />
                  </div>
                  {sortedFilteredCategories.length === 0 && (
                    <p className="py-4 text-center text-sm text-slate-500">No categories match &ldquo;{categorySearch}&rdquo;</p>
                  )}
                  <div className="grid gap-3 lg:grid-cols-2">
                    {sortedFilteredCategories.map((cat) => {
                      const isActive = String(metadata.rootCategoryId || '') === String(cat.id)
                      const childCount = cat.children?.length || 0
                      return (
                        <button
                          key={cat.id}
                          type="button"
                          onClick={() => {
                            setIsCategoryChooserOpen(false)
                            onRootCategoryChange(String(cat.id))
                          }}
                          className={[
                            'rounded-2xl border px-4 py-4 text-left transition-all',
                            isActive
                              ? 'border-purple-400/40 bg-purple-400/12 shadow-[0_0_0_1px_rgba(192,132,252,0.15)]'
                              : 'border-white/10 bg-white/[0.03] hover:border-white/20 hover:bg-white/[0.05]',
                          ].join(' ')}
                        >
                          <div className="flex items-start justify-between gap-3">
                            <div>
                              <div className={`text-sm font-semibold ${isActive ? 'text-purple-200' : 'text-white'}`}>{cat.name}</div>
                              <div className="mt-1 text-[11px] text-slate-500">{childCount > 0 ? `${childCount} subcategories` : 'Standalone'}</div>
                            </div>
                            <span className={`rounded-full px-2 py-1 text-[11px] ${isActive ? 'bg-purple-300/15 text-purple-200' : 'bg-white/[0.05] text-slate-500'}`}>
                              {isActive ? 'Selected' : 'Choose'}
                            </span>
                          </div>
                        </button>
                      )
                    })}
                  </div>
                </div>
              )}

              {metadataErrors.category && <p className="mt-3 text-xs text-red-300">{metadataErrors.category}</p>}
            </div>
          </>
        )}

        {/* ── Subcategory ── */}
        {selectedRoot && subCategories.length > 0 && (
          <>
            <div className="my-5 border-t border-white/8" />
            <div>
              <div className="mb-3 flex items-center justify-between gap-2">
                <p className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">Subcategory</p>
                <span className="text-[11px] text-slate-600">{subCategories.length} available</span>
              </div>

              {!metadata.subCategoryId && requiresSubCategory && (
                <div className="mb-3 rounded-xl border border-amber-400/20 bg-amber-400/10 px-3 py-2 text-sm text-amber-100">
                  Subcategory still needs to be selected.
                </div>
              )}

              {selectedSubCategory && !isSubCategoryChooserOpen && (
                <div className="rounded-2xl border border-cyan-400/25 bg-cyan-400/[0.07] p-4">
                  <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                    <div>
                      <div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-cyan-200/70">Selected</div>
                      <div className="mt-0.5 text-base font-semibold text-white">{selectedSubCategory.name}</div>
                      <div className="mt-1 text-xs text-slate-500">
                        Path: <span className="text-slate-300">{selectedRoot.name}</span> / <span className="text-cyan-200">{selectedSubCategory.name}</span>
                      </div>
                    </div>
                    <button
                      type="button"
                      onClick={() => { setSubCategorySearch(''); setIsSubCategoryChooserOpen(true) }}
                      className="inline-flex items-center justify-center rounded-xl border border-white/10 bg-white/[0.05] px-3 py-2 text-sm font-medium text-slate-200 transition hover:border-white/20 hover:bg-white/[0.08] hover:text-white"
                    >
                      Change
                    </button>
                  </div>
                </div>
              )}

              {(!selectedSubCategory || isSubCategoryChooserOpen) && (
                <div className="space-y-3">
                  <div className="relative">
                    <svg className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-500" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fillRule="evenodd" d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z" clipRule="evenodd" /></svg>
                    <input
                      type="search"
                      value={subCategorySearch}
                      onChange={(e) => setSubCategorySearch(e.target.value)}
                      placeholder="Search subcategories…"
                      className="w-full rounded-xl border border-white/10 bg-white/[0.04] py-2.5 pl-9 pr-4 text-sm text-white placeholder:text-slate-500 focus:border-cyan-400/40 focus:outline-none focus:ring-1 focus:ring-cyan-400/30"
                    />
                  </div>
                  {sortedFilteredSubCategories.length === 0 && (
                    <p className="py-4 text-center text-sm text-slate-500">No subcategories match &ldquo;{subCategorySearch}&rdquo;</p>
                  )}
                  <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
                    {sortedFilteredSubCategories.map((sub) => {
                      const isActive = String(metadata.subCategoryId || '') === String(sub.id)
                      return (
                        <button
                          key={sub.id}
                          type="button"
                          onClick={() => {
                            setIsSubCategoryChooserOpen(false)
                            onSubCategoryChange(String(sub.id))
                          }}
                          className={[
                            'group rounded-2xl border px-4 py-3 text-left transition-all',
                            isActive
                              ? 'border-cyan-400/40 bg-cyan-400/[0.13] shadow-[0_0_0_1px_rgba(34,211,238,0.14)]'
                              : 'border-white/10 bg-white/[0.04] hover:border-white/20 hover:bg-white/[0.06]',
                          ].join(' ')}
                        >
                          <div className="flex items-start justify-between gap-3">
                            <div className="min-w-0">
                              <div className={['text-sm font-semibold transition-colors', isActive ? 'text-cyan-100' : 'text-slate-100 group-hover:text-white'].join(' ')}>
                                {sub.name}
                              </div>
                              <div className={['mt-1 text-xs', isActive ? 'text-cyan-200/80' : 'text-slate-500 group-hover:text-slate-300'].join(' ')}>
                                Subcategory
                              </div>
                            </div>
                            <span className={['shrink-0 rounded-full px-2.5 py-1 text-[11px] font-medium', isActive ? 'bg-cyan-300/15 text-cyan-100' : 'bg-white/[0.05] text-slate-500 group-hover:text-slate-300'].join(' ')}>
                              {isActive ? 'Selected' : 'Choose'}
                            </span>
                          </div>
                        </button>
                      )
                    })}
                  </div>
                </div>
              )}
            </div>
          </>
        )}

        {selectedRoot && subCategories.length === 0 && selectedRoot && (
          <div className="mt-5 rounded-2xl border border-white/8 bg-white/[0.02] px-4 py-3 text-sm text-slate-500">
            <span className="font-medium text-slate-300">{selectedRoot.name}</span> has no subcategories — selecting it is enough.
          </div>
        )}
      </section>

      {Array.isArray(groupOptions) && groupOptions.length > 0 && (
        <section className="rounded-2xl border border-white/10 bg-[radial-gradient(ellipse_at_top_left,_rgba(56,189,248,0.08),_transparent_42%),linear-gradient(180deg,rgba(255,255,255,0.04),rgba(255,255,255,0.02))] p-5 sm:p-6">
          <div className="mb-5 flex flex-wrap items-start justify-between gap-3">
            <div>
              <h3 className="text-sm font-semibold text-white">Publisher attribution</h3>
              <p className="mt-1 text-xs text-white/55">Publish personally or switch into a group identity while preserving author and contributor credits.</p>
            </div>
            {metadata.group ? <span className="rounded-full border border-sky-300/20 bg-sky-300/10 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-sky-100">Group publish</span> : <span className="rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-300">Personal publish</span>}
          </div>

          <label className="block">
            <span className="text-sm font-medium text-white/90">Publishing identity</span>
            <select
              value={metadata.group || ''}
              onChange={(event) => onGroupChange?.(event.target.value)}
              className="mt-2 w-full rounded-xl border border-white/15 bg-black/20 px-3 py-3 text-sm text-white outline-none transition focus:border-sky-300/40"
            >
              <option value="">Personal profile</option>
              {groupOptions.map((group) => (
                <option key={group.slug} value={group.slug}>{group.name}</option>
              ))}
            </select>
          </label>

          {metadata.group && (
            <div className="mt-5 grid gap-5 lg:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]">
              <div>
                <label className="block">
                  <span className="text-sm font-medium text-white/90">Primary author</span>
                  <select
                    value={metadata.primaryAuthorUserId || ''}
                    onChange={(event) => onPrimaryAuthorChange?.(event.target.value)}
                    className="mt-2 w-full rounded-xl border border-white/15 bg-black/20 px-3 py-3 text-sm text-white outline-none transition focus:border-sky-300/40"
                  >
                    {currentContributorOptions.map((user) => (
                      <option key={user.id} value={user.id}>{user.name || user.username}</option>
                    ))}
                  </select>
                </label>
                <p className="mt-2 text-xs text-slate-400">The primary author is shown as the lead creator for this group-published artwork.</p>
              </div>

              <div>
                <div className="flex items-center justify-between gap-3">
                  <span className="text-sm font-medium text-white/90">Contributors</span>
                  <span className="text-xs text-slate-500">Optional</span>
                </div>
                <div className="mt-2 grid gap-2">
                  {currentContributorOptions.filter((user) => Number(user.id) !== Number(metadata.primaryAuthorUserId)).map((user) => {
                    const active = Array.isArray(metadata.contributorUserIds) && metadata.contributorUserIds.some((id) => Number(id) === Number(user.id))
                    const creditMeta = contributorCredits?.[user.id] || contributorCredits?.[String(user.id)] || { creditRole: '', isPrimary: false }

                    return (
                      <div
                        key={user.id}
                        className={[
                          'rounded-2xl border px-3 py-3 transition',
                          active
                            ? 'border-sky-300/30 bg-sky-300/10 text-white'
                            : 'border-white/10 bg-white/[0.03] text-slate-200 hover:border-white/20 hover:bg-white/[0.06]',
                        ].join(' ')}
                      >
                        <div className="flex items-center gap-3">
                          {user.avatar_url ? <img src={user.avatar_url} alt={user.name || user.username} className="h-10 w-10 rounded-2xl object-cover" /> : <div className="flex h-10 w-10 items-center justify-center rounded-2xl border border-white/10 bg-white/[0.03] text-slate-400"><i className="fa-solid fa-user" /></div>}
                          <div className="min-w-0 flex-1">
                            <div className="truncate text-sm font-semibold">{user.name || user.username}</div>
                            <div className="truncate text-xs text-slate-400">@{user.username}</div>
                          </div>
                          <button
                            type="button"
                            onClick={() => onContributorToggle?.(user.id)}
                            className={[
                              'inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs font-semibold transition',
                              active
                                ? 'border-sky-300/40 bg-sky-300/20 text-sky-50'
                                : 'border-white/10 bg-white/[0.03] text-white/70 hover:border-white/20 hover:text-white',
                            ].join(' ')}
                          >
                            <span className={['inline-flex h-4 w-4 items-center justify-center rounded-full border text-[10px]', active ? 'border-sky-300/40 bg-sky-300/20 text-sky-50' : 'border-white/10 bg-white/[0.03] text-white/35'].join(' ')}>{active ? '✓' : ''}</span>
                            {active ? 'Added' : 'Add credit'}
                          </button>
                        </div>

                        {active ? (
                          <div className="mt-4 grid gap-3 md:grid-cols-[minmax(0,1fr)_auto] md:items-end">
                            <label className="block">
                              <span className="text-xs font-medium uppercase tracking-[0.16em] text-slate-300">Credit role</span>
                              <input
                                type="text"
                                value={creditMeta.creditRole || ''}
                                onChange={(event) => onContributorRoleChange?.(user.id, event.target.value)}
                                placeholder="Colorist, concept support, layout..."
                                aria-label={`Credit role for ${user.name || user.username}`}
                                className="mt-2 w-full rounded-xl border border-white/15 bg-black/20 px-3 py-3 text-sm text-white outline-none transition focus:border-sky-300/40"
                              />
                            </label>
                            <button
                              type="button"
                              onClick={() => onContributorPrimaryChange?.(user.id)}
                              aria-pressed={creditMeta.isPrimary ? 'true' : 'false'}
                              aria-label={`Mark ${user.name || user.username} as lead supporting credit`}
                              className={[
                                'inline-flex items-center justify-center rounded-xl border px-3 py-3 text-sm font-medium transition',
                                creditMeta.isPrimary
                                  ? 'border-emerald-300/35 bg-emerald-400/12 text-emerald-100'
                                  : 'border-white/10 bg-white/[0.03] text-slate-200 hover:border-white/20 hover:bg-white/[0.06] hover:text-white',
                              ].join(' ')}
                            >
                              {creditMeta.isPrimary ? 'Lead support' : 'Set lead support'}
                            </button>
                          </div>
                        ) : null}
                      </div>
                    )
                  })}
                </div>
              </div>
            </div>
          )}
        </section>
      )}

      {/* Title, tags, description, rights */}
      <UploadSidebar
        showHeader={false}
        metadata={metadata}
        suggestedTags={suggestedTags}
        errors={metadataErrors}
        publishMode={publishMode}
        scheduledAt={scheduledAt}
        timezone={timezone}
        onPublishModeChange={onPublishModeChange}
        onScheduleAt={onScheduleAt}
        onChangeTitle={onChangeTitle}
        onChangeTags={onChangeTags}
        onChangeDescription={onChangeDescription}
        onToggleMature={onToggleMature}
        onToggleRights={onToggleRights}
      />
    </div>
  )
}
