import React, { useEffect, useState } from 'react'
import { router } from '@inertiajs/react'
import { studioSurface, trackStudioEvent } from '../../utils/studioEvents'
import ConfirmDangerModal from './ConfirmDangerModal'
import NovaSelect from '../ui/NovaSelect'
import Checkbox from '../ui/Checkbox'

function formatDate(value) {
  if (!value) return 'Unscheduled'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return 'Unscheduled'
  return date.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })
}

function metricValue(item, key) {
  return Number(item?.metrics?.[key] ?? 0).toLocaleString()
}

function readinessClasses(readiness) {
  if (!readiness) return 'border-white/15 bg-white/5 text-slate-300'
  if (readiness.can_publish && readiness.score >= readiness.max) return 'border-emerald-400/30 bg-emerald-400/10 text-emerald-100'
  if (readiness.can_publish) return 'border-sky-400/30 bg-sky-400/10 text-sky-100'
  return 'border-amber-400/30 bg-amber-400/10 text-amber-100'
}

function statusClasses(status) {
  switch (status) {
    case 'published':
      return 'border-emerald-400/30 bg-emerald-400/10 text-emerald-200'
    case 'draft':
    case 'pending_review':
      return 'border-amber-400/30 bg-amber-400/10 text-amber-100'
    case 'scheduled':
    case 'processing':
      return 'border-sky-400/30 bg-sky-400/10 text-sky-100'
    case 'archived':
    case 'hidden':
    case 'rejected':
      return 'border-white/15 bg-white/5 text-slate-300'
    default:
      return 'border-white/15 bg-white/5 text-slate-200'
  }
}

function itemReadiness(item) {
  if (item?.status === 'published') return null
  return item?.workflow?.readiness ?? null
}

function buildPaginationPages(current, last) {
  if (last <= 1) return [1]
  if (last <= 7) {
    return Array.from({ length: last }, (_, index) => index + 1)
  }

  const pages = new Set([1, 2, current - 1, current, current + 1, last - 1, last])
  const sorted = [...pages]
    .filter((page) => page >= 1 && page <= last)
    .sort((left, right) => left - right)

  const result = []
  for (let index = 0; index < sorted.length; index += 1) {
    if (index > 0 && sorted[index] - sorted[index - 1] > 1) {
      result.push('ellipsis')
    }
    result.push(sorted[index])
  }

  return result
}

function bulkErrorMessage(payload, fallback = 'Bulk action failed.') {
  if (Array.isArray(payload?.errors) && payload.errors.length > 0) {
    return payload.errors[0]
  }

  return payload?.message
    || payload?.error
    || payload?.errors?.confirm?.[0]
    || payload?.errors?.action?.[0]
    || fallback
}

function stripHtml(value) {
  if (typeof value !== 'string') return ''
  return value.replace(/<[^>]*>/g, '').trim()
}

function ActionLink({ href, icon, label, onClick }) {
  if (!href) return null

  return (
    <a
      href={href}
      onClick={onClick}
      className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.03] px-3 py-1.5 text-xs font-medium text-slate-200 transition hover:border-white/20 hover:bg-white/[0.06]"
    >
      <i className={`${icon} text-[11px]`} />
      <span>{label}</span>
    </a>
  )
}

function RequestActionButton({ action, onExecute, busyKey }) {
  if (!action || action.type !== 'request') return null

  const isBusy = busyKey === `${action.key}:${action.url}`

  return (
    <button
      type="button"
      onClick={() => onExecute(action)}
      disabled={isBusy}
      className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.03] px-3 py-1.5 text-xs font-medium text-slate-200 transition hover:border-white/20 hover:bg-white/[0.06] disabled:cursor-not-allowed disabled:opacity-50"
    >
      <i className={`${action.icon} text-[11px]`} />
      <span>{isBusy ? 'Working...' : action.label}</span>
    </button>
  )
}

function PreviewLink({ item }) {
  if (!item?.preview_url) return null

  return <ActionLink href={item.preview_url} icon="fa-solid fa-eye" label="Preview" />
}

function GridCard({ item, onExecuteAction, busyKey }) {
  const readiness = itemReadiness(item)

  const handleEditClick = () => {
    trackStudioEvent('studio_item_edited', {
      surface: studioSurface(),
      module: item.module,
      item_module: item.module,
      item_id: item.numeric_id,
      meta: {
        action: 'edit',
      },
    })
  }

  return (
    <article className="overflow-hidden rounded-[28px] border border-white/10 bg-white/[0.03] shadow-[0_18px_50px_rgba(3,7,18,0.22)] transition hover:-translate-y-0.5 hover:border-white/20">
      <div className="relative aspect-[1.15/1] overflow-hidden bg-slate-950/70">
        {item.image_url ? (
          <img src={item.image_url} alt={item.title} className="h-full w-full object-cover" loading="lazy" />
        ) : (
          <div className="flex h-full items-center justify-center bg-[radial-gradient(circle_at_top,_rgba(56,189,248,0.18),_transparent_55%),linear-gradient(135deg,_rgba(15,23,42,0.9),_rgba(2,6,23,0.95))] text-slate-400">
            <i className={`${item.module_icon} text-3xl`} />
          </div>
        )}
        <div className="absolute left-4 top-4 inline-flex items-center gap-2 rounded-full border border-black/10 bg-black/45 px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-white backdrop-blur-md">
          <i className={`${item.module_icon} text-[10px]`} />
          <span>{item.module_label}</span>
        </div>
      </div>
      <div className="space-y-4 p-5">
        <div className="flex items-start justify-between gap-3">
          <div className="min-w-0">
            <h3 className="truncate text-base font-semibold text-white">{item.title}</h3>
            <p className="mt-1 truncate text-sm text-slate-400">{item.subtitle || item.visibility || 'Untitled metadata'}</p>
          </div>
          <span className={`inline-flex shrink-0 items-center rounded-full border px-2.5 py-1 text-[11px] font-medium capitalize ${statusClasses(item.status)}`}>
            {String(item.status || 'unknown').replace('_', ' ')}
          </span>
        </div>

        {readiness && (
          <div className="flex flex-wrap items-center gap-2">
            <span className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium ${readinessClasses(readiness)}`}>
              {readiness.label}
            </span>
            {item.workflow.is_stale_draft && (
              <span className="inline-flex items-center rounded-full border border-amber-400/30 bg-amber-400/10 px-2.5 py-1 text-[11px] font-medium text-amber-100">
                Stale draft
              </span>
            )}
            <span className="text-[11px] uppercase tracking-[0.16em] text-slate-500">
              {readiness.score}/{readiness.max} ready
            </span>
          </div>
        )}

        <p className="line-clamp-2 min-h-[2.5rem] text-sm text-slate-300/90">
          {stripHtml(item.description) || 'No description yet.'}
        </p>

        {Array.isArray(readiness?.missing) && readiness.missing.length > 0 && (
          <div className="rounded-2xl border border-white/5 bg-slate-950/35 p-3 text-xs text-slate-400">
            {readiness.missing.slice(0, 2).join(' • ')}
          </div>
        )}

        <div className="grid grid-cols-3 gap-2 rounded-2xl border border-white/5 bg-slate-950/40 p-3 text-xs text-slate-400">
          <div>
            <div className="text-[10px] uppercase tracking-[0.16em]">Views</div>
            <div className="mt-1 text-sm font-semibold text-white">{metricValue(item, 'views')}</div>
          </div>
          <div>
            <div className="text-[10px] uppercase tracking-[0.16em]">Reactions</div>
            <div className="mt-1 text-sm font-semibold text-white">{metricValue(item, 'appreciation')}</div>
          </div>
          <div>
            <div className="text-[10px] uppercase tracking-[0.16em]">Comments</div>
            <div className="mt-1 text-sm font-semibold text-white">{metricValue(item, 'comments')}</div>
          </div>
        </div>

        <div className="flex flex-wrap items-center gap-2 text-xs text-slate-500">
          <span>Updated {formatDate(item.updated_at)}</span>
          {item.published_at && <span>Published {formatDate(item.published_at)}</span>}
        </div>

        <div className="flex flex-wrap gap-2">
          <ActionLink href={item.edit_url || item.manage_url} icon="fa-solid fa-pen-to-square" label="Edit" onClick={handleEditClick} />
          <PreviewLink item={item} />
          <ActionLink href={item.analytics_url} icon="fa-solid fa-chart-line" label="Analytics" />
          <ActionLink href={item.view_url} icon="fa-solid fa-arrow-up-right-from-square" label="Open" />
          {(item.actions || []).map((action) => (
            <RequestActionButton key={`${item.id}-${action.key}`} action={{ ...action, item_id: item.numeric_id, item_module: item.module }} onExecute={onExecuteAction} busyKey={busyKey} />
          ))}
        </div>

        {Array.isArray(item.workflow?.cross_module_actions) && item.workflow.cross_module_actions.length > 0 && (
          <div className="flex flex-wrap gap-2 border-t border-white/5 pt-3">
            {item.workflow.cross_module_actions.slice(0, 2).map((action) => (
              <ActionLink key={`${item.id}-${action.label}`} href={action.href} icon={action.icon} label={action.label} />
            ))}
          </div>
        )}
      </div>
    </article>
  )
}

function ListRow({ item, onExecuteAction, busyKey }) {
  const readiness = itemReadiness(item)

  const handleEditClick = () => {
    trackStudioEvent('studio_item_edited', {
      surface: studioSurface(),
      module: item.module,
      item_module: item.module,
      item_id: item.numeric_id,
      meta: {
        action: 'edit',
      },
    })
  }

  return (
    <article className="grid gap-4 rounded-[24px] border border-white/10 bg-white/[0.03] p-4 transition hover:border-white/20 md:grid-cols-[120px_minmax(0,1fr)_auto] md:items-center">
      <div className="h-24 overflow-hidden rounded-2xl bg-slate-950/60">
        {item.image_url ? (
          <img src={item.image_url} alt={item.title} className="h-full w-full object-cover" loading="lazy" />
        ) : (
          <div className="flex h-full items-center justify-center text-slate-400">
            <i className={`${item.module_icon} text-2xl`} />
          </div>
        )}
      </div>

      <div className="min-w-0">
        <div className="flex flex-wrap items-center gap-2">
          <span className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-300">
            <i className={`${item.module_icon} text-[10px]`} />
            {item.module_label}
          </span>
          <span className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium capitalize ${statusClasses(item.status)}`}>
            {String(item.status || 'unknown').replace('_', ' ')}
          </span>
        </div>
        <h3 className="mt-3 truncate text-lg font-semibold text-white">{item.title}</h3>
        <p className="mt-1 text-sm text-slate-400">{item.subtitle || item.visibility || 'Untitled metadata'}</p>
        <p className="mt-3 line-clamp-2 text-sm text-slate-300/90">{stripHtml(item.description) || 'No description yet.'}</p>
        <div className="mt-3 flex flex-wrap gap-2">
          {readiness && (
            <span className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium ${readinessClasses(readiness)}`}>
              {readiness.label}
            </span>
          )}
          {item.workflow?.is_stale_draft && (
            <span className="inline-flex items-center rounded-full border border-amber-400/30 bg-amber-400/10 px-2.5 py-1 text-[11px] font-medium text-amber-100">
              Stale draft
            </span>
          )}
        </div>
        <div className="mt-3 flex flex-wrap gap-4 text-xs text-slate-500">
          <span>{metricValue(item, 'views')} views</span>
          <span>{metricValue(item, 'appreciation')} reactions</span>
          <span>{metricValue(item, 'comments')} comments</span>
          <span>Updated {formatDate(item.updated_at)}</span>
        </div>
        {Array.isArray(readiness?.missing) && readiness.missing.length > 0 && (
          <div className="mt-3 text-xs text-slate-500">{readiness.missing.slice(0, 2).join(' • ')}</div>
        )}
      </div>

      <div className="flex flex-wrap gap-2 md:justify-end">
        <ActionLink href={item.edit_url || item.manage_url} icon="fa-solid fa-pen-to-square" label="Edit" onClick={handleEditClick} />
        <PreviewLink item={item} />
        <ActionLink href={item.analytics_url} icon="fa-solid fa-chart-line" label="Analytics" />
        <ActionLink href={item.view_url} icon="fa-solid fa-arrow-up-right-from-square" label="Open" />
        {(item.actions || []).map((action) => (
          <RequestActionButton key={`${item.id}-${action.key}`} action={{ ...action, item_id: item.numeric_id, item_module: item.module }} onExecute={onExecuteAction} busyKey={busyKey} />
        ))}
        {(item.workflow?.cross_module_actions || []).slice(0, 2).map((action) => (
          <ActionLink key={`${item.id}-${action.label}`} href={action.href} icon={action.icon} label={action.label} />
        ))}
      </div>
    </article>
  )
}

function materializeFilter(filter, pendingFilters) {
  if (filter?.key !== 'category') {
    return filter
  }

  const selectedContentType = pendingFilters?.content_type || 'all'
  const options = Array.isArray(filter.options)
    ? filter.options.filter((option) => option.value === 'all'
      || selectedContentType === 'all'
      || option.content_type_slug === selectedContentType)
    : filter.options

  return {
    ...filter,
    options,
  }
}

function selectOptions(options = []) {
  return options.map((option) => ({
    value: option.value,
    label: option.label,
    group: option.group,
    disabled: option.disabled,
    icon: option.icon,
  }))
}

function FilterField({ label, children }) {
  return (
    <div className="space-y-2 text-sm text-slate-300">
      <span className="block text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500">{label}</span>
      {children}
    </div>
  )
}

function AdvancedFilterControl({ filter, onChange, value }) {
  const controlValue = value ?? filter.value

  if (filter.type === 'select') {
    const options = selectOptions(filter.options || [])
    const searchable = filter.searchable ?? options.length > 8

    return (
      <FilterField label={filter.label}>
        <NovaSelect
          id={`studio-filter-${filter.key}`}
          options={options}
          value={controlValue || 'all'}
          onChange={(nextValue) => onChange(filter.key, nextValue ?? 'all')}
          placeholder={filter.label}
          searchable={searchable}
        />
      </FilterField>
    )
  }

  return (
    <FilterField label={filter.label}>
      <input
        type="search"
        value={controlValue || ''}
        onChange={(event) => onChange(filter.key, event.target.value)}
        placeholder={filter.placeholder || filter.label}
        className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none transition placeholder:text-slate-500 focus:border-sky-300/40 focus:bg-black/30"
      />
    </FilterField>
  )
}

export default function StudioContentBrowser({
  listing,
  quickCreate = [],
  hideModuleFilter = false,
  hideBucketFilter = false,
  defaultSort = 'updated_desc',
  sortStorageKey = null,
  emptyTitle = 'Nothing here yet',
  emptyBody = 'Try adjusting filters or create something new.',
}) {
  const [viewMode, setViewMode] = useState('grid')
  const [busyKey, setBusyKey] = useState(null)
  const [selectedIds, setSelectedIds] = useState([])
  const [bulkBusy, setBulkBusy] = useState(false)
  const [optimisticRemovedIds, setOptimisticRemovedIds] = useState([])
  const [pendingFilters, setPendingFilters] = useState({
    q: '',
    bucket: 'all',
    sort: defaultSort,
    content_type: 'all',
    category: 'all',
    tag: '',
  })
  const [deleteDialog, setDeleteDialog] = useState({
    open: false,
    title: '',
    message: '',
    target: null,
  })
  const filters = listing?.filters || {}
  const items = listing?.items || []
  const meta = listing?.meta || {}
  const advancedFilters = listing?.advanced_filters || []
  const visibleItems = items.filter((item) => !optimisticRemovedIds.includes(Number(item.numeric_id)))
  const currentModule = filters.module || listing?.module || items[0]?.module || null
  const visibleQuickCreate = hideModuleFilter && currentModule && currentModule !== 'all'
    ? quickCreate.filter((action) => action.key === currentModule)
    : quickCreate
  const supportsArtworkBulk = currentModule === 'artworks' && items.every((item) => item.module === 'artworks')
  const selectableIds = supportsArtworkBulk
    ? visibleItems.map((item) => Number(item.numeric_id)).filter((value) => Number.isInteger(value) && value > 0)
    : []
  const allVisibleSelected = selectableIds.length > 0 && selectableIds.every((id) => selectedIds.includes(id))
  const selectedOnPage = selectedIds.filter((id) => selectableIds.includes(id))
  const visibleTotal = Math.max(0, Number(meta.total || 0) - optimisticRemovedIds.length)
  const currentPage = Math.max(1, Number(meta.current_page || 1))
  const lastPage = Math.max(1, Number(meta.last_page || 1))
  const perPage = Math.max(1, Number(meta.per_page || visibleItems.length || 24))
  const rangeStart = visibleTotal === 0 ? 0 : ((currentPage - 1) * perPage) + 1
  const rangeEnd = visibleTotal === 0 ? 0 : Math.min(visibleTotal, rangeStart + Math.max(visibleItems.length, 1) - 1)
  const paginationPages = buildPaginationPages(currentPage, lastPage)
  const filterControlCount = 1 + (hideModuleFilter ? 0 : 1) + (hideBucketFilter ? 0 : 1) + 1 + advancedFilters.length + 1
  const filterGridClass = filterControlCount <= 4
    ? 'xl:grid-cols-4'
    : filterControlCount === 5
      ? 'xl:grid-cols-5'
      : filterControlCount === 6
        ? 'xl:grid-cols-6'
        : 'xl:grid-cols-6 2xl:grid-cols-7'

  useEffect(() => {
    const stored = window.localStorage.getItem('studio-content-view')
    if (stored === 'grid' || stored === 'list' || stored === 'table') {
      setViewMode(stored)
      return
    }

    if (listing?.default_view === 'grid' || listing?.default_view === 'list' || listing?.default_view === 'table') {
      setViewMode(listing.default_view)
    }
  }, [listing?.default_view])

  useEffect(() => {
    setSelectedIds((current) => current.filter((id) => selectableIds.includes(id)))
  }, [visibleItems, supportsArtworkBulk])

  useEffect(() => {
    setOptimisticRemovedIds([])
  }, [items])

  useEffect(() => {
    setPendingFilters({
      q: filters.q || '',
      bucket: filters.bucket || 'all',
      sort: filters.sort || defaultSort,
      content_type: filters.content_type || 'all',
      category: filters.category || 'all',
      tag: filters.tag || '',
    })
  }, [filters.q, filters.bucket, filters.sort, filters.content_type, filters.category, filters.tag, defaultSort])

  useEffect(() => {
    if (!sortStorageKey) {
      return
    }

    const params = new URLSearchParams(window.location.search)
    if (params.has('sort')) {
      return
    }

    const storedSort = window.localStorage.getItem(sortStorageKey)
    const sortOptions = new Set((listing?.sort_options || []).map((option) => option.value))
    const activeSort = filters.sort || defaultSort

    if (!storedSort || !sortOptions.has(storedSort) || storedSort === activeSort) {
      return
    }

    router.get(window.location.pathname, {
      ...filters,
      sort: storedSort,
      page: 1,
    }, {
      preserveScroll: true,
      preserveState: true,
      replace: true,
    })
  }, [sortStorageKey, listing?.sort_options, filters, defaultSort])

  const updateQuery = (patch) => {
    const next = {
      ...filters,
      ...patch,
    }

    if (patch.page == null) {
      next.page = 1
    }

    trackStudioEvent('studio_filter_used', {
      surface: studioSurface(),
      module: filters.module || listing?.module || null,
      meta: {
        patch,
      },
    })

    if (sortStorageKey && typeof next.sort === 'string' && next.sort !== '') {
      window.localStorage.setItem(sortStorageKey, next.sort)
    }

    router.get(window.location.pathname, next, {
      preserveScroll: true,
      preserveState: true,
      replace: true,
    })
  }

  const updateView = (nextMode) => {
    setViewMode(nextMode)
    window.localStorage.setItem('studio-content-view', nextMode)
    trackStudioEvent('studio_filter_used', {
      surface: studioSurface(),
      module: filters.module || listing?.module || null,
      meta: {
        view_mode: nextMode,
      },
    })
  }

  const setPendingFilter = (key, value) => {
    setPendingFilters((current) => {
      if (key === 'content_type') {
        return {
          ...current,
          content_type: value,
          category: 'all',
        }
      }

      return {
        ...current,
        [key]: value,
      }
    })
  }

  const submitSearch = () => {
    updateQuery({
      q: pendingFilters.q,
      bucket: pendingFilters.bucket,
      sort: pendingFilters.sort,
      content_type: pendingFilters.content_type,
      category: pendingFilters.category,
      tag: pendingFilters.tag,
    })
  }

  const addOptimisticallyRemovedIds = (ids) => {
    setOptimisticRemovedIds((current) => Array.from(new Set([
      ...current,
      ...ids.map((value) => Number(value)).filter((value) => Number.isInteger(value) && value > 0),
    ])))
  }

  const toggleSelected = (numericId) => {
    setSelectedIds((current) => current.includes(numericId)
      ? current.filter((id) => id !== numericId)
      : [...current, numericId])
  }

  const toggleSelectAllVisible = () => {
    if (!supportsArtworkBulk || selectableIds.length === 0) {
      return
    }

    setSelectedIds((current) => {
      if (allVisibleSelected) {
        return current.filter((id) => !selectableIds.includes(id))
      }

      return Array.from(new Set([...current, ...selectableIds]))
    })
  }

  const executeBulkAction = async (actionKey) => {
    if (!supportsArtworkBulk || selectedIds.length === 0 || bulkBusy) {
      return
    }

    const labels = {
      publish: 'publish',
      unpublish: 'move to draft',
      archive: 'archive',
      unarchive: 'restore',
      delete: 'delete permanently',
    }

    if (actionKey === 'delete') {
      setDeleteDialog({
        open: true,
        title: `Delete ${selectedIds.length} artwork${selectedIds.length === 1 ? '' : 's'}?`,
        message: 'This permanently removes the selected artworks. This cannot be undone.',
        target: {
          kind: 'bulk',
          actionKey,
          ids: [...selectedIds],
        },
      })
      return
    }

    if (!window.confirm(`Are you sure you want to ${labels[actionKey] || actionKey} ${selectedIds.length} artwork${selectedIds.length === 1 ? '' : 's'}?`)) {
      return
    }

    setBulkBusy(true)

    try {
      const response = await fetch('/api/studio/artworks/bulk', {
        method: 'POST',
        credentials: 'same-origin',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
          'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
          'X-Requested-With': 'XMLHttpRequest',
        },
        body: JSON.stringify({
          action: actionKey,
          artwork_ids: selectedIds,
        }),
      })

      const payload = await response.json().catch(() => ({}))

      if (!response.ok) {
        throw new Error(bulkErrorMessage(payload))
      }

      trackStudioEvent('studio_filter_used', {
        surface: studioSurface(),
        module: 'artworks',
        meta: {
          bulk_action: actionKey,
          count: selectedIds.length,
        },
      })

      setSelectedIds([])
      router.reload({ preserveScroll: true, preserveState: true })
    } catch (error) {
      window.alert(error?.message || 'Bulk action failed.')
    } finally {
      setBulkBusy(false)
    }
  }

  const closeDeleteDialog = () => {
    setDeleteDialog({
      open: false,
      title: '',
      message: '',
      target: null,
    })
  }

  const confirmDeleteDialog = async () => {
    const target = deleteDialog.target
    if (!target) {
      closeDeleteDialog()
      return
    }

    if (target.kind === 'bulk') {
      setBulkBusy(true)

      try {
        const response = await fetch('/api/studio/artworks/bulk', {
          method: 'POST',
          credentials: 'same-origin',
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
            'X-Requested-With': 'XMLHttpRequest',
          },
          body: JSON.stringify({
            action: 'delete',
            artwork_ids: target.ids,
            confirm: 'DELETE',
          }),
        })

        const payload = await response.json().catch(() => ({}))

        if (!response.ok) {
          throw new Error(bulkErrorMessage(payload))
        }

        trackStudioEvent('studio_filter_used', {
          surface: studioSurface(),
          module: 'artworks',
          meta: {
            bulk_action: 'delete',
            count: target.ids.length,
          },
        })

        addOptimisticallyRemovedIds(target.ids)
        setSelectedIds([])
        closeDeleteDialog()
        router.reload({ preserveScroll: true, preserveState: true })
      } catch (error) {
        window.alert(error?.message || 'Bulk action failed.')
      } finally {
        setBulkBusy(false)
      }

      return
    }

    if (target.kind === 'single') {
      const action = target.action
      const requestKey = `${action.key}:${action.url}`
      setBusyKey(requestKey)

      try {
        const response = await fetch(action.url, {
          method: String(action.method || 'post').toUpperCase(),
          credentials: 'same-origin',
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
            'X-Requested-With': 'XMLHttpRequest',
          },
          body: action.payload ? JSON.stringify(action.payload) : undefined,
        })

        const payload = await response.json().catch(() => ({}))

        if (!response.ok) {
          throw new Error(payload?.message || payload?.error || 'Request failed')
        }

        addOptimisticallyRemovedIds(action.payload?.artwork_ids || [])
        closeDeleteDialog()

        if (action.redirect_pattern && payload?.data?.id) {
          window.location.assign(action.redirect_pattern.replace('__ID__', String(payload.data.id)))
          return
        }

        if (payload?.redirect) {
          window.location.assign(payload.redirect)
          return
        }

        router.reload({ preserveScroll: true, preserveState: true })
      } catch (error) {
        window.alert(error?.message || 'Action failed.')
      } finally {
        setBusyKey(null)
      }
    }
  }

  const executeAction = async (action) => {
    if (!action?.url || action.type !== 'request') {
      return
    }

    if (action.key === 'delete') {
      setDeleteDialog({
        open: true,
        title: 'Delete artwork permanently?',
        message: action.confirm || 'This artwork will be permanently removed and cannot be restored.',
        target: {
          kind: 'single',
          action,
        },
      })
      return
    }

    if (action.confirm && !window.confirm(action.confirm)) {
      return
    }

    const requestKey = `${action.key}:${action.url}`
    setBusyKey(requestKey)

    try {
      const response = await fetch(action.url, {
        method: String(action.method || 'post').toUpperCase(),
        credentials: 'same-origin',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
          'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '',
          'X-Requested-With': 'XMLHttpRequest',
        },
        body: action.payload ? JSON.stringify(action.payload) : undefined,
      })

      const payload = await response.json().catch(() => ({}))

      if (!response.ok) {
        throw new Error(payload?.message || payload?.error || 'Request failed')
      }

      if (action.key === 'archive') {
        trackStudioEvent('studio_item_archived', {
          surface: studioSurface(),
          module: filters.module || null,
          item_module: action.item_module || null,
          item_id: action.item_id || null,
          meta: {
            action: action.key,
            url: action.url,
          },
        })
      }

      if (action.key === 'restore') {
        trackStudioEvent('studio_item_restored', {
          surface: studioSurface(),
          module: filters.module || null,
          item_module: action.item_module || null,
          item_id: action.item_id || null,
          meta: {
            action: action.key,
            url: action.url,
          },
        })
      }

      if (action.redirect_pattern && payload?.data?.id) {
        window.location.assign(action.redirect_pattern.replace('__ID__', String(payload.data.id)))
        return
      }

      if (payload?.redirect) {
        window.location.assign(payload.redirect)
        return
      }

      router.reload({ preserveScroll: true, preserveState: true })
    } catch (error) {
      window.alert(error?.message || 'Action failed.')
    } finally {
      setBusyKey(null)
    }
  }

  return (
    <div className="space-y-6">
      <section className="rounded-[30px] border border-white/10 bg-[radial-gradient(circle_at_top_left,_rgba(34,197,94,0.12),_transparent_35%),radial-gradient(circle_at_bottom_right,_rgba(56,189,248,0.12),_transparent_40%),linear-gradient(135deg,_rgba(15,23,42,0.86),_rgba(2,6,23,0.96))] p-5 shadow-[0_22px_60px_rgba(2,6,23,0.28)] lg:p-6">
        <div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-end">
          <div className={`grid gap-3 md:grid-cols-2 ${filterGridClass}`}>
            <FilterField label="Search">
              <input
                type="search"
                value={pendingFilters.q}
                onChange={(event) => setPendingFilter('q', event.target.value)}
                placeholder="Title, description, module"
                className="w-full rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-white outline-none transition placeholder:text-slate-500 focus:border-sky-300/40 focus:bg-black/30"
              />
            </FilterField>

            {!hideModuleFilter && (
              <FilterField label="Module">
                <NovaSelect
                  id="studio-filter-module"
                  options={selectOptions(listing?.module_options || [])}
                  value={filters.module || 'all'}
                  onChange={(nextValue) => updateQuery({ module: nextValue ?? 'all' })}
                  placeholder="All content"
                  searchable={false}
                />
              </FilterField>
            )}

            {!hideBucketFilter && (
              <FilterField label="Status">
                <NovaSelect
                  id="studio-filter-status"
                  options={selectOptions(listing?.bucket_options || [])}
                  value={pendingFilters.bucket}
                  onChange={(nextValue) => setPendingFilter('bucket', nextValue ?? 'all')}
                  placeholder="All"
                  searchable={false}
                />
              </FilterField>
            )}

            <FilterField label="Sort">
              <NovaSelect
                id="studio-filter-sort"
                options={selectOptions(listing?.sort_options || [])}
                value={pendingFilters.sort}
                onChange={(nextValue) => setPendingFilter('sort', nextValue ?? defaultSort)}
                placeholder="Recently updated"
                searchable={false}
              />
            </FilterField>

            {advancedFilters.map((filter) => {
              const resolvedFilter = materializeFilter(filter, pendingFilters)

              return (
              <AdvancedFilterControl
                key={filter.key}
                filter={resolvedFilter}
                value={filter.key === 'content_type' || filter.key === 'category' || filter.key === 'tag' ? pendingFilters[filter.key] : undefined}
                onChange={(key, value) => {
                  if (key === 'content_type' || key === 'category' || key === 'tag') {
                    setPendingFilter(key, value)
                    return
                  }

                  updateQuery({ [key]: value })
                }}
              />
              )
            })}

            <div className="flex items-end">
              <button
                type="button"
                onClick={submitSearch}
                className="inline-flex w-full items-center justify-center gap-2 rounded-2xl border border-sky-300/20 bg-sky-300/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15"
              >
                <i className="fa-solid fa-magnifying-glass" />
                <span>Search</span>
              </button>
            </div>
          </div>

          <div className="flex flex-wrap items-center gap-3 lg:justify-end">
            <div className="inline-flex rounded-full border border-white/10 bg-black/20 p-1">
              {[
                { value: 'grid', icon: 'fa-solid fa-table-cells-large', label: 'Grid view' },
                { value: 'list', icon: 'fa-solid fa-list', label: 'List view' },
                { value: 'table', icon: 'fa-solid fa-table-list', label: 'Table view' },
              ].map((option) => (
                <button
                  key={option.value}
                  type="button"
                  onClick={() => updateView(option.value)}
                  className={`inline-flex items-center gap-2 rounded-full px-3 py-2 text-xs font-semibold transition ${viewMode === option.value ? 'bg-white text-slate-950' : 'text-slate-300 hover:text-white'}`}
                >
                  <i className={option.icon} />
                  <span className="hidden sm:inline">{option.label}</span>
                </button>
              ))}
            </div>

            {visibleQuickCreate.map((action) => (
              <a
                key={action.key}
                href={action.url}
                onClick={() => trackStudioEvent('studio_quick_create_used', {
                  surface: studioSurface(),
                  module: action.key,
                  meta: {
                    href: action.url,
                    label: action.label,
                  },
                })}
                className="inline-flex items-center gap-2 rounded-full border border-sky-300/20 bg-sky-300/10 px-4 py-2 text-xs font-semibold text-sky-100 transition hover:border-sky-300/35 hover:bg-sky-300/15"
              >
                <i className={action.icon} />
                <span>New {action.label}</span>
              </a>
            ))}
          </div>
        </div>
      </section>

      <div className="flex flex-wrap items-center justify-between gap-3 text-sm text-slate-400">
        <p>
          Showing <span className="font-semibold text-white">{visibleItems.length}</span> of <span className="font-semibold text-white">{visibleTotal.toLocaleString()}</span> items
        </p>
        <p>Page {currentPage} of {lastPage}</p>
      </div>

      {viewMode === 'table' && supportsArtworkBulk && (
        <section className="flex flex-wrap items-center justify-between gap-3 rounded-[24px] border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-300">
          <div className="flex flex-wrap items-center gap-3">
            <div className="inline-flex items-center gap-2 text-sm text-slate-300">
              <Checkbox
                checked={allVisibleSelected}
                onChange={toggleSelectAllVisible}
                label="Select page"
              />
            </div>
            <span className="text-slate-500">
              {selectedIds.length > 0 ? `${selectedIds.length} selected` : 'Select artworks to run bulk actions'}
            </span>
          </div>

          <div className="flex flex-wrap gap-2">
            {[
              { key: 'publish', label: 'Publish', icon: 'fa-solid fa-rocket' },
              { key: 'unpublish', label: 'Draft', icon: 'fa-solid fa-file-pen' },
              { key: 'archive', label: 'Archive', icon: 'fa-solid fa-box-archive' },
              { key: 'unarchive', label: 'Restore', icon: 'fa-solid fa-rotate-left' },
              { key: 'delete', label: 'Delete', icon: 'fa-solid fa-trash' },
            ].map((action) => (
              <button
                key={action.key}
                type="button"
                disabled={selectedIds.length === 0 || bulkBusy}
                onClick={() => executeBulkAction(action.key)}
                className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-black/20 px-3 py-2 text-xs font-semibold text-slate-200 transition hover:border-white/20 hover:bg-black/30 disabled:cursor-not-allowed disabled:opacity-40"
              >
                <i className={action.icon} />
                <span>{bulkBusy ? 'Working...' : action.label}</span>
              </button>
            ))}
          </div>
        </section>
      )}

      {visibleItems.length > 0 ? (
        viewMode === 'grid' ? (
          <div className="grid gap-5 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
            {visibleItems.map((item) => <GridCard key={item.id} item={item} onExecuteAction={executeAction} busyKey={busyKey} />)}
          </div>
        ) : viewMode === 'list' ? (
          <div className="space-y-4">
            {visibleItems.map((item) => <ListRow key={item.id} item={item} onExecuteAction={executeAction} busyKey={busyKey} />)}
          </div>
        ) : (
          <div className="overflow-hidden rounded-[28px] border border-white/10 bg-white/[0.03]">
            <div className="overflow-x-auto">
              <table className="min-w-full divide-y divide-white/10 text-left text-sm text-slate-300">
                <thead className="bg-black/20 text-[11px] uppercase tracking-[0.18em] text-slate-500">
                  <tr>
                    {supportsArtworkBulk && (
                      <th scope="col" className="w-12 px-4 py-3">
                        <Checkbox
                          checked={allVisibleSelected}
                          onChange={toggleSelectAllVisible}
                          aria-label="Select all artworks on this page"
                        />
                      </th>
                    )}
                    <th scope="col" className="px-4 py-3">Item</th>
                    <th scope="col" className="px-4 py-3">Status</th>
                    <th scope="col" className="px-4 py-3">Category</th>
                    <th scope="col" className="px-4 py-3">Updated</th>
                    <th scope="col" className="px-4 py-3">Stats</th>
                    <th scope="col" className="px-4 py-3">Actions</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-white/5">
                  {visibleItems.map((item) => {
                    const isSelected = selectedOnPage.includes(Number(item.numeric_id))

                    return (
                      <tr key={item.id} className="align-top transition hover:bg-white/[0.03]">
                        {supportsArtworkBulk && (
                          <td className="px-4 py-4">
                            <Checkbox
                              checked={isSelected}
                              onChange={() => toggleSelected(Number(item.numeric_id))}
                              aria-label={`Select ${item.title}`}
                            />
                          </td>
                        )}
                        <td className="px-4 py-4">
                          <div className="flex min-w-[280px] items-start gap-3">
                            <div className="h-16 w-16 shrink-0 overflow-hidden rounded-2xl bg-slate-950/60">
                              {item.image_url ? (
                                <img src={item.image_url} alt={item.title} className="h-full w-full object-cover" loading="lazy" />
                              ) : (
                                <div className="flex h-full items-center justify-center text-slate-500">
                                  <i className={`${item.module_icon} text-lg`} />
                                </div>
                              )}
                            </div>
                            <div className="min-w-0">
                              <div className="flex flex-wrap items-center gap-2">
                                <span className="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/[0.04] px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-300">
                                  <i className={`${item.module_icon} text-[10px]`} />
                                  {item.module_label}
                                </span>
                                <span className="text-xs text-slate-500">#{item.numeric_id}</span>
                              </div>
                              <div className="mt-2 truncate text-sm font-semibold text-white">{item.title}</div>
                              <div className="mt-1 text-xs text-slate-400">{item.subtitle || item.visibility || 'Untitled metadata'}</div>
                              {Array.isArray(item.taxonomies?.tags) && item.taxonomies.tags.length > 0 && (
                                <div className="mt-2 flex flex-wrap gap-1.5">
                                  {item.taxonomies.tags.slice(0, 3).map((tag) => (
                                    <span key={`${item.id}-${tag.slug}`} className="rounded-full border border-white/10 px-2 py-1 text-[10px] text-slate-400">
                                      {tag.name}
                                    </span>
                                  ))}
                                </div>
                              )}
                            </div>
                          </div>
                        </td>
                        <td className="px-4 py-4">
                          <div className="space-y-2">
                            <span className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium capitalize ${statusClasses(item.status)}`}>
                              {String(item.status || 'unknown').replace('_', ' ')}
                            </span>
                            {itemReadiness(item) && (
                              <div>
                                <span className={`inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium ${readinessClasses(itemReadiness(item))}`}>
                                  {itemReadiness(item).label}
                                </span>
                              </div>
                            )}
                          </div>
                        </td>
                        <td className="px-4 py-4 text-sm text-slate-400">
                          <div>{item.subtitle || item.taxonomies?.categories?.[0]?.name || 'Uncategorized'}</div>
                          <div className="mt-1 text-xs text-slate-500">{item.visibility || 'private'}</div>
                        </td>
                        <td className="px-4 py-4 text-sm text-slate-400">
                          <div>Updated {formatDate(item.updated_at)}</div>
                          <div className="mt-1 text-xs text-slate-500">Created {formatDate(item.created_at)}</div>
                          {item.published_at && <div className="mt-1 text-xs text-slate-500">Published {formatDate(item.published_at)}</div>}
                        </td>
                        <td className="px-4 py-4 text-sm text-slate-400">
                          <div>{metricValue(item, 'views')} views</div>
                          <div className="mt-1">{metricValue(item, 'appreciation')} reactions</div>
                          <div className="mt-1">{metricValue(item, 'comments')} comments</div>
                        </td>
                        <td className="px-4 py-4">
                          <div className="flex min-w-[220px] flex-wrap gap-2">
                            <ActionLink href={item.edit_url || item.manage_url} icon="fa-solid fa-pen-to-square" label="Edit" />
                            <PreviewLink item={item} />
                            <ActionLink href={item.view_url} icon="fa-solid fa-arrow-up-right-from-square" label="Open" />
                            {(item.actions || []).slice(0, 2).map((action) => (
                              <RequestActionButton key={`${item.id}-${action.key}`} action={{ ...action, item_id: item.numeric_id, item_module: item.module }} onExecute={executeAction} busyKey={busyKey} />
                            ))}
                          </div>
                        </td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>
          </div>
        )
      ) : (
        <section className="rounded-[28px] border border-dashed border-white/15 bg-white/[0.02] px-6 py-16 text-center">
          <h3 className="text-xl font-semibold text-white">{emptyTitle}</h3>
          <p className="mx-auto mt-3 max-w-xl text-sm text-slate-400">{emptyBody}</p>
        </section>
      )}

      <div className="rounded-[24px] border border-white/10 bg-white/[0.03] px-4 py-4 text-sm text-slate-300">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
          <div className="space-y-1">
            <div className="text-xs uppercase tracking-[0.2em] text-slate-500">Creator Studio</div>
            <p className="text-sm text-slate-400">
              {visibleTotal > 0
                ? <>Showing <span className="font-semibold text-white">{rangeStart.toLocaleString()}-{rangeEnd.toLocaleString()}</span> of <span className="font-semibold text-white">{visibleTotal.toLocaleString()}</span></>
                : 'No items to display'}
            </p>
          </div>

          {lastPage > 1 && (
            <nav aria-label="Studio pagination" className="flex flex-col gap-3 lg:items-end">
              <div className="flex flex-wrap items-center gap-2">
                <button
                  type="button"
                  disabled={currentPage <= 1}
                  onClick={() => updateQuery({ page: 1 })}
                  className="inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-2 text-xs font-semibold text-slate-300 transition hover:border-white/20 hover:bg-white/[0.04] disabled:cursor-not-allowed disabled:opacity-40"
                >
                  <i className="fa-solid fa-angles-left" />
                  <span className="hidden sm:inline">First</span>
                </button>

                <button
                  type="button"
                  disabled={currentPage <= 1}
                  onClick={() => updateQuery({ page: Math.max(1, currentPage - 1) })}
                  className="inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-2 text-xs font-semibold text-slate-300 transition hover:border-white/20 hover:bg-white/[0.04] disabled:cursor-not-allowed disabled:opacity-40"
                >
                  <i className="fa-solid fa-arrow-left" />
                  <span>Previous</span>
                </button>

                <div className="flex flex-wrap items-center gap-1.5">
                  {paginationPages.map((page, index) => page === 'ellipsis' ? (
                    <span key={`ellipsis-${index}`} className="inline-flex h-10 min-w-[2.5rem] items-center justify-center text-xs font-semibold uppercase tracking-[0.16em] text-slate-500">
                      ...
                    </span>
                  ) : (
                    <button
                      key={page}
                      type="button"
                      aria-current={page === currentPage ? 'page' : undefined}
                      onClick={() => updateQuery({ page })}
                      className={`inline-flex h-10 min-w-[2.5rem] items-center justify-center rounded-2xl border px-3 text-sm font-semibold transition ${page === currentPage ? 'border-sky-400/30 bg-sky-300/15 text-white shadow-[0_10px_24px_rgba(14,165,233,0.16)]' : 'border-white/10 text-slate-300 hover:border-white/20 hover:bg-white/[0.04]'}`}
                    >
                      {page}
                    </button>
                  ))}
                </div>

                <button
                  type="button"
                  disabled={currentPage >= lastPage}
                  onClick={() => updateQuery({ page: currentPage + 1 })}
                  className="inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-2 text-xs font-semibold text-slate-300 transition hover:border-white/20 hover:bg-white/[0.04] disabled:cursor-not-allowed disabled:opacity-40"
                >
                  <span>Next</span>
                  <i className="fa-solid fa-arrow-right" />
                </button>

                <button
                  type="button"
                  disabled={currentPage >= lastPage}
                  onClick={() => updateQuery({ page: lastPage })}
                  className="inline-flex items-center gap-2 rounded-full border border-white/10 px-3 py-2 text-xs font-semibold text-slate-300 transition hover:border-white/20 hover:bg-white/[0.04] disabled:cursor-not-allowed disabled:opacity-40"
                >
                  <span className="hidden sm:inline">Last</span>
                  <i className="fa-solid fa-angles-right" />
                </button>
              </div>

              <p className="text-xs text-slate-500">
                Jump by page number or use first/last for longer queues.
              </p>
            </nav>
          )}
        </div>
      </div>

      <ConfirmDangerModal
        open={deleteDialog.open}
        onClose={closeDeleteDialog}
        onConfirm={confirmDeleteDialog}
        title={deleteDialog.title}
        message={deleteDialog.message}
        confirmText="DELETE"
      />
    </div>
  )
}