import React from 'react'
import { Head, Link, usePage } from '@inertiajs/react'
import StudioLayout from '../../Layouts/StudioLayout'
import NovaCardCanvasPreview from '../../components/nova-cards/NovaCardCanvasPreview'
import NovaCardTemplatePicker from '../../components/nova-cards/NovaCardTemplatePicker'
import NovaCardGradientPicker from '../../components/nova-cards/NovaCardGradientPicker'
import NovaCardFontPicker from '../../components/nova-cards/NovaCardFontPicker'
import NovaCardAutosaveIndicator from '../../components/nova-cards/NovaCardAutosaveIndicator'
import NovaCardPresetPicker from '../../components/nova-cards/NovaCardPresetPicker'

const defaultMobileSteps = [
  { key: 'format', label: 'Format', description: 'Choose the canvas shape and basic direction.' },
  { key: 'background', label: 'Template & Background', description: 'Pick the visual foundation for the card.' },
  { key: 'content', label: 'Text', description: 'Write the quote, author, and source.' },
  { key: 'style', label: 'Style', description: 'Fine-tune typography and layout.' },
  { key: 'preview', label: 'Preview', description: 'Check the live composition before publish.' },
  { key: 'publish', label: 'Publish', description: 'Review metadata and release settings.' },
]

const overlayOptions = [
  { value: 'none', label: 'None' },
  { value: 'dark-soft', label: 'Dark Soft' },
  { value: 'dark-strong', label: 'Dark Strong' },
  { value: 'light-soft', label: 'Light Soft' },
]

const layoutPresetMap = {
  quote_heavy: { alignment: 'center', position: 'center', padding: 'comfortable', max_width: 'balanced' },
  author_emphasis: { alignment: 'left', position: 'lower-middle', padding: 'comfortable', max_width: 'compact' },
  centered: { alignment: 'center', position: 'center', padding: 'airy', max_width: 'compact' },
  minimal: { alignment: 'left', position: 'upper-middle', padding: 'tight', max_width: 'wide' },
}

function deepMerge(target, source) {
  if (!source || typeof source !== 'object') return target

  const next = Array.isArray(target) ? [...target] : { ...(target || {}) }

  Object.entries(source).forEach(([key, value]) => {
    if (Array.isArray(value)) {
      next[key] = value
      return
    }

    if (value && typeof value === 'object') {
      next[key] = deepMerge(next[key], value)
      return
    }

    next[key] = value
  })

  return next
}

function pillClasses(active) {
  return `rounded-full border px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.16em] transition ${active ? 'border-sky-300/30 bg-sky-400/15 text-sky-100' : 'border-white/10 bg-white/[0.03] text-slate-300 hover:bg-white/[0.05]'}`
}

function defaultTextBlocks() {
  return [
    { key: 'title', type: 'title', text: 'Untitled card', enabled: true, style: { role: 'eyebrow' } },
    { key: 'quote', type: 'quote', text: 'Your next quote starts here.', enabled: true, style: { role: 'headline' } },
    { key: 'author', type: 'author', text: '', enabled: false, style: { role: 'byline' } },
    { key: 'source', type: 'source', text: '', enabled: false, style: { role: 'caption' } },
  ]
}

function truncateText(value, limit = 96) {
  const normalized = String(value || '').trim()
  if (normalized.length <= limit) return normalized
  return `${normalized.slice(0, limit - 1).trimEnd()}...`
}

function projectTextValue(project, type, fallbackKey = null) {
  const blocks = Array.isArray(project?.text_blocks) ? project.text_blocks : []
  const block = blocks.find((item) => item?.type === type && String(item?.text || '').trim() !== '')
  if (block) return String(block.text || '')
  if (!fallbackKey) return ''
  return String(project?.content?.[fallbackKey] || '')
}

function summarizeProjectSnapshot(project) {
  const blocks = Array.isArray(project?.text_blocks) ? project.text_blocks : []
  const enabledBlocks = blocks.filter((block) => block?.enabled !== false && String(block?.text || '').trim() !== '').length

  return {
    title: truncateText(projectTextValue(project, 'title', 'title') || 'Untitled card', 64),
    quote: truncateText(projectTextValue(project, 'quote', 'quote_text'), 88),
    blockCount: blocks.length,
    enabledBlocks,
    layout: String(project?.layout?.layout || 'quote_heavy'),
    font: String(project?.typography?.font_preset || 'modern-sans'),
    background: String(project?.background?.gradient_preset || project?.background?.solid_color || project?.background?.type || 'gradient'),
  }
}

function compareProjectSnapshots(currentProject, versionProject) {
  if (!versionProject || typeof versionProject !== 'object') {
    return ['Snapshot unavailable']
  }

  const changes = []
  const currentSummary = summarizeProjectSnapshot(currentProject)
  const versionSummary = summarizeProjectSnapshot(versionProject)

  if (currentSummary.title !== versionSummary.title) changes.push('Title copy changed')
  if (currentSummary.quote !== versionSummary.quote) changes.push('Quote copy changed')
  if (currentSummary.blockCount !== versionSummary.blockCount) changes.push(`Block count ${versionSummary.blockCount}`)
  if (currentSummary.layout !== versionSummary.layout) changes.push(`Layout ${versionSummary.layout.replace(/_/g, ' ')}`)
  if (currentSummary.font !== versionSummary.font) changes.push(`Font ${versionSummary.font.replace(/-/g, ' ')}`)
  if (currentSummary.background !== versionSummary.background) changes.push('Background treatment changed')

  return changes.length ? changes.slice(0, 4) : ['Matches current draft']
}

function normalizeProject(project, options, card = null) {
  const defaultGradient = options.gradient_presets?.[0] || null
  const defaultFont = options.font_presets?.[0] || null
  const content = project?.content || {}
  const blocks = Array.isArray(project?.text_blocks) && project.text_blocks.length ? project.text_blocks : defaultTextBlocks().map((block) => ({
    ...block,
    text: block.type === 'title'
      ? (card?.title || content.title || block.text)
      : block.type === 'quote'
        ? (card?.quote_text || content.quote_text || block.text)
        : block.type === 'author'
          ? (card?.quote_author || content.quote_author || '')
          : (card?.quote_source || content.quote_source || ''),
    enabled: block.type === 'title' || block.type === 'quote' ? true : Boolean(block.type === 'author' ? (card?.quote_author || content.quote_author) : (card?.quote_source || content.quote_source)),
  }))

  return {
    schema_version: Number(project?.schema_version || 3),
    meta: project?.meta || { editor: 'nova-cards-v3' },
    template: project?.template || { id: card?.template_id || null, slug: card?.template?.slug || null },
    content: {
      title: card?.title || content.title || 'Untitled card',
      quote_text: card?.quote_text || content.quote_text || 'Your next quote starts here.',
      quote_author: card?.quote_author || content.quote_author || '',
      quote_source: card?.quote_source || content.quote_source || '',
    },
    text_blocks: blocks,
    layout: {
      layout: project?.layout?.layout || 'quote_heavy',
      position: project?.layout?.position || 'center',
      alignment: project?.layout?.alignment || 'center',
      padding: project?.layout?.padding || 'comfortable',
      max_width: project?.layout?.max_width || 'balanced',
    },
    typography: {
      font_preset: project?.typography?.font_preset || defaultFont?.key || 'modern-sans',
      text_color: project?.typography?.text_color || '#ffffff',
      accent_color: project?.typography?.accent_color || '#e0f2fe',
      quote_size: Number(project?.typography?.quote_size || 72),
      author_size: Number(project?.typography?.author_size || 28),
      letter_spacing: Number(project?.typography?.letter_spacing || 0),
      line_height: Number(project?.typography?.line_height || 1.2),
      shadow_preset: project?.typography?.shadow_preset || 'soft',
    },
    background: {
      type: project?.background?.type || card?.background_type || 'gradient',
      gradient_preset: project?.background?.gradient_preset || defaultGradient?.key || 'midnight-nova',
      gradient_colors: project?.background?.gradient_colors || defaultGradient?.colors || ['#0f172a', '#1d4ed8'],
      solid_color: project?.background?.solid_color || '#111827',
      background_image_id: project?.background?.background_image_id || card?.background_image_id || null,
      overlay_style: project?.background?.overlay_style || 'dark-soft',
      focal_position: project?.background?.focal_position || 'center',
      blur_level: Number(project?.background?.blur_level || 0),
      opacity: Number(project?.background?.opacity || 50),
    },
    canvas: {
      density: project?.canvas?.density || 'standard',
      safe_zone: project?.canvas?.safe_zone !== false,
    },
    frame: {
      preset: project?.frame?.preset || 'none',
      color: project?.frame?.color || null,
      width: Number(project?.frame?.width || 1),
    },
    effects: {
      color_grade: project?.effects?.color_grade || 'none',
      effect_preset: project?.effects?.effect_preset || 'none',
      intensity: Number(project?.effects?.intensity || 50),
    },
    export_preferences: {
      allow_export: project?.export_preferences?.allow_export !== false,
      default_format: project?.export_preferences?.default_format || 'preview',
    },
    source_context: {
      style_family: project?.source_context?.style_family || null,
      palette_family: project?.source_context?.palette_family || null,
      editor_mode: project?.source_context?.editor_mode || card?.editor_mode_last_used || 'full',
    },
    decorations: Array.isArray(project?.decorations) ? project.decorations : [],
    assets: {
      pack_ids: Array.isArray(project?.assets?.pack_ids) ? project.assets.pack_ids : [],
      template_pack_ids: Array.isArray(project?.assets?.template_pack_ids) ? project.assets.template_pack_ids : [],
      items: Array.isArray(project?.assets?.items) ? project.assets.items : [],
    },
  }
}

function syncTextBlocks(blocks, type, text) {
  const list = Array.isArray(blocks) ? [...blocks] : defaultTextBlocks()
  const index = list.findIndex((block) => block.type === type)
  const next = {
    key: type,
    type,
    text,
    enabled: type === 'title' || type === 'quote' ? true : Boolean(String(text || '').trim()),
    style: list[index]?.style || {},
  }

  if (index === -1) {
    list.push(next)
    return list
  }

  list[index] = { ...list[index], ...next }
  return list
}

function normalizeCard(card, options) {
  if (!card) {
    const defaultTemplate = options.templates?.[0] || null
    const defaultCategory = options.categories?.[0] || null
    const project = normalizeProject(null, options)

    return {
      id: null,
      title: 'Untitled card',
      quote_text: 'Your next quote starts here.',
      quote_author: '',
      quote_source: '',
      description: '',
      format: options.formats?.[0]?.key || 'square',
      visibility: 'private',
      status: 'draft',
      moderation_status: 'pending',
      allow_download: true,
      background_type: 'gradient',
      template_id: defaultTemplate?.id || null,
      category_id: defaultCategory?.id || null,
      background_image_id: null,
      tags: [],
      preview_url: null,
      public_url: null,
      schema_version: 2,
      allow_remix: true,
      likes_count: 0,
      favorites_count: 0,
      saves_count: 0,
      remixes_count: 0,
      challenge_entries_count: 0,
      lineage: { original_card: null, root_card: null },
      editor_mode_last_used: 'full',
      project_json: project,
    }
  }

  return {
    ...card,
    tags: Array.isArray(card.tags) ? card.tags : [],
    allow_remix: card.allow_remix !== false,
    project_json: normalizeProject(card.project_json || {}, options, card),
  }
}

function buildPayload(card, tagInput) {
  return {
    title: card.title,
    quote_text: card.quote_text,
    quote_author: card.quote_author,
    quote_source: card.quote_source,
    description: card.description,
    format: card.format,
    visibility: card.visibility,
    allow_download: Boolean(card.allow_download),
    allow_remix: Boolean(card.allow_remix),
    allow_background_reuse: Boolean(card.allow_background_reuse),
    allow_export: Boolean(card.allow_export !== false),
    style_family: card.style_family || null,
    palette_family: card.palette_family || null,
    editor_mode_last_used: card.editor_mode_last_used || card.project_json?.source_context?.editor_mode || 'full',
    background_type: card.background_type,
    background_image_id: card.background_image_id,
    template_id: card.template_id,
    category_id: card.category_id,
    tags: String(tagInput || '')
      .split(',')
      .map((item) => item.trim())
      .filter(Boolean),
    project_json: card.project_json,
  }
}

function fillPattern(pattern, replacements) {
  let resolved = String(pattern || '')
  Object.entries(replacements).forEach(([key, value]) => {
    resolved = resolved.replace(`__${key}__`, String(value))
  })
  return resolved
}

function apiUrl(pattern, id) {
  return fillPattern(pattern, { CARD: id })
}

export default function StudioCardEditor() {
  const { props } = usePage()
  const editorOptions = props.editorOptions || {}
  const endpoints = props.endpoints || {}
  const previewMode = Boolean(props.previewMode)
  const mobileSteps = Array.isArray(props.mobileSteps) && props.mobileSteps.length ? props.mobileSteps : defaultMobileSteps

  const [card, setCard] = React.useState(() => normalizeCard(props.card, editorOptions))
  const [cardId, setCardId] = React.useState(props.card?.id || null)
  const [tagInput, setTagInput] = React.useState(() => (props.card?.tags || []).map((tag) => tag.name).join(', '))
  const [versions, setVersions] = React.useState(() => Array.isArray(props.versions) ? props.versions : [])
  const [collections, setCollections] = React.useState([])
  const [selectedCollectionId, setSelectedCollectionId] = React.useState('')
  const [autosaveStatus, setAutosaveStatus] = React.useState(props.card ? 'saved' : 'idle')
  const [autosaveMessage, setAutosaveMessage] = React.useState(props.card ? 'Loaded' : 'Preparing draft')
  const [busy, setBusy] = React.useState(false)
  const [uploading, setUploading] = React.useState(false)
  const [currentMobileStep, setCurrentMobileStep] = React.useState(previewMode ? 'preview' : mobileSteps[0]?.key || 'format')
  // v3 state
  const [creatorPresets, setCreatorPresets] = React.useState(() => editorOptions.creator_presets || {})
  const [aiSuggestions, setAiSuggestions] = React.useState(null)
  const [loadingAi, setLoadingAi] = React.useState(false)
  const [exportStatus, setExportStatus] = React.useState(null)
  const [requestingExport, setRequestingExport] = React.useState(false)
  const [activeExportType, setActiveExportType] = React.useState('preview')
  const createStarted = React.useRef(false)
  const lastSerialized = React.useRef(JSON.stringify(buildPayload(normalizeCard(props.card, editorOptions), tagInput)))

  React.useEffect(() => {
    setCurrentMobileStep(previewMode ? 'preview' : mobileSteps[0]?.key || 'format')
  }, [mobileSteps, previewMode])

  function replaceTextBlocks(nextBlocks) {
    setCard((current) => {
      const blocks = Array.isArray(nextBlocks) ? nextBlocks : []
      const next = { ...current }
      next.project_json = deepMerge(current.project_json || {}, { text_blocks: blocks })

      const quoteBlock = blocks.find((block) => block?.type === 'quote')
      const titleBlock = blocks.find((block) => block?.type === 'title')
      const authorBlock = blocks.find((block) => block?.type === 'author')
      const sourceBlock = blocks.find((block) => block?.type === 'source')
      next.title = titleBlock?.text || next.title
      next.quote_text = quoteBlock?.text || next.quote_text
      next.quote_author = authorBlock?.text || ''
      next.quote_source = sourceBlock?.text || ''
      next.project_json.content = {
        ...(next.project_json.content || {}),
        title: next.title,
        quote_text: next.quote_text,
        quote_author: next.quote_author,
        quote_source: next.quote_source,
      }

      return next
    })
  }

  function loadVersions(targetCardId) {
    if (!targetCardId || !endpoints.draftVersionsPattern) return
    window.axios.get(apiUrl(endpoints.draftVersionsPattern, targetCardId))
      .then((response) => {
        setVersions(Array.isArray(response.data?.data) ? response.data.data : [])
      })
      .catch(() => {})
  }

  function loadCollections() {
    if (!endpoints.collectionsIndex) return
    window.axios.get(endpoints.collectionsIndex)
      .then((response) => {
        const items = Array.isArray(response.data?.data) ? response.data.data : []
        setCollections(items)
        if (!selectedCollectionId && items[0]?.id) {
          setSelectedCollectionId(String(items[0].id))
        }
      })
      .catch(() => {})
  }

  React.useEffect(() => {
    if (!cardId) return
    loadVersions(cardId)
    loadCollections()
  }, [cardId])

  React.useEffect(() => {
    if (cardId || createStarted.current) return
    createStarted.current = true
    setBusy(true)

    window.axios.post(endpoints.draftStore, {
      format: card.format,
      template_id: card.template_id,
      category_id: card.category_id,
    }).then((response) => {
      const nextCard = normalizeCard(response.data.data, editorOptions)
      setCard(nextCard)
      setCardId(nextCard.id)
      setAutosaveStatus('saved')
      setAutosaveMessage('Draft created')
      lastSerialized.current = JSON.stringify(buildPayload(nextCard, tagInput))
    }).catch(() => {
      setAutosaveStatus('error')
      setAutosaveMessage('Could not create draft')
    }).finally(() => {
      setBusy(false)
    })
  }, [card, cardId, editorOptions, endpoints.draftStore, tagInput])

  React.useEffect(() => {
    if (!cardId || busy || uploading) return

    const payload = buildPayload(card, tagInput)
    const serialized = JSON.stringify(payload)
    if (serialized === lastSerialized.current) return

    setAutosaveStatus('saving')
    setAutosaveMessage('Saving draft')

    const timer = window.setTimeout(() => {
      window.axios.post(apiUrl(endpoints.draftAutosavePattern, cardId), payload)
        .then((response) => {
          const nextCard = normalizeCard(response.data.data, editorOptions)
          setCard(nextCard)
          lastSerialized.current = JSON.stringify(buildPayload(nextCard, tagInput))
          setAutosaveStatus('saved')
          setAutosaveMessage('All changes saved')
        })
        .catch(() => {
          setAutosaveStatus('error')
          setAutosaveMessage('Autosave failed')
        })
    }, 900)

    return () => window.clearTimeout(timer)
  }, [busy, card, cardId, editorOptions, endpoints.draftAutosavePattern, tagInput, uploading])

  function updateCard(partial, projectPatch = null) {
    setCard((current) => {
      const next = { ...current, ...partial }
      if (projectPatch) {
        next.project_json = deepMerge(current.project_json || {}, projectPatch)
      }
      return next
    })
  }

  function updateTextField(key, value) {
    const typeMap = {
      title: 'title',
      quote_text: 'quote',
      quote_author: 'author',
      quote_source: 'source',
    }

    setCard((current) => {
      const next = { ...current, [key]: value }
      next.project_json = deepMerge(current.project_json || {}, {
        content: { [key]: value },
        text_blocks: syncTextBlocks(current.project_json?.text_blocks, typeMap[key], value),
      })
      return next
    })
  }

  function updateTextBlock(index, patch) {
    const blocks = Array.isArray(card.project_json?.text_blocks) ? [...card.project_json.text_blocks] : []
    blocks[index] = { ...blocks[index], ...patch }
    replaceTextBlocks(blocks)
  }

  function addTextBlock(type = 'body') {
    const nextBlock = {
      key: `${type}-${Date.now()}`,
      type,
      text: '',
      enabled: true,
      style: {},
    }
    replaceTextBlocks([...(Array.isArray(card.project_json?.text_blocks) ? card.project_json.text_blocks : []), nextBlock])
  }

  function removeTextBlock(index) {
    const blocks = Array.isArray(card.project_json?.text_blocks) ? card.project_json.text_blocks : []
    replaceTextBlocks(blocks.filter((_, itemIndex) => itemIndex !== index))
  }

  function moveTextBlock(index, direction) {
    const blocks = Array.isArray(card.project_json?.text_blocks) ? [...card.project_json.text_blocks] : []
    const nextIndex = index + direction

    if (nextIndex < 0 || nextIndex >= blocks.length) {
      return
    }

    const [moved] = blocks.splice(index, 1)
    blocks.splice(nextIndex, 0, moved)
    replaceTextBlocks(blocks)
  }

  function setEditorMode(mode) {
    updateCard({ editor_mode_last_used: mode }, { source_context: { editor_mode: mode } })
  }

  function handleTemplateSelect(template) {
    const layoutPreset = template.config_json?.layout || 'quote_heavy'

    updateCard(
      { template_id: template.id },
      {
        template: { id: template.id, slug: template.slug },
        layout: {
          layout: layoutPreset,
          ...(layoutPresetMap[layoutPreset] || {}),
          alignment: template.config_json?.text_align || layoutPresetMap[layoutPreset]?.alignment || 'center',
        },
        typography: {
          font_preset: template.config_json?.font_preset || card.project_json?.typography?.font_preset,
          text_color: template.config_json?.text_color || card.project_json?.typography?.text_color,
        },
        background: {
          gradient_preset: template.config_json?.gradient_preset || card.project_json?.background?.gradient_preset,
          overlay_style: template.config_json?.overlay_style || card.project_json?.background?.overlay_style,
        },
      },
    )
  }

  function handleGradientSelect(gradient) {
    updateCard({ background_type: 'gradient' }, {
      background: {
        type: 'gradient',
        gradient_preset: gradient.key,
        gradient_colors: gradient.colors,
      },
    })
  }

  function handleFontSelect(font) {
    updateCard({}, {
      typography: {
        font_preset: font.key,
      },
    })
  }

  function reloadPresets() {
    if (!endpoints.presetsIndex) return
    window.axios.get(endpoints.presetsIndex)
      .then((response) => {
        const data = response.data?.data || response.data || {}
        setCreatorPresets(data)
      })
      .catch(() => {})
  }

  function handleApplyPresetPatch(patch) {
    setCard((current) => ({
      ...current,
      project_json: deepMerge(current.project_json || {}, patch),
    }))
  }

  function fetchAiSuggestions() {
    if (!cardId || !endpoints.aiSuggestPattern) return
    const url = endpoints.aiSuggestPattern.replace('__CARD__', cardId)
    setLoadingAi(true)
    window.axios.get(url)
      .then((response) => setAiSuggestions(response.data?.suggestions || response.data || null))
      .catch(() => {})
      .finally(() => setLoadingAi(false))
  }

  function applyAiTagSuggestions(tags) {
    if (!Array.isArray(tags) || tags.length === 0) return
    const existing = tagInput ? tagInput.split(',').map((t) => t.trim()).filter(Boolean) : []
    const merged = [...new Set([...existing, ...tags])]
    setTagInput(merged.join(', '))
  }

  function requestExport(exportType) {
    if (!cardId || !endpoints.exportPattern) return
    const url = endpoints.exportPattern.replace('__CARD__', cardId)
    setRequestingExport(true)
    setExportStatus(null)
    setActiveExportType(exportType)
    const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || ''
    window.axios.post(url, { export_type: exportType }, { headers: { 'X-CSRF-TOKEN': csrfToken } })
      .then((response) => {
        const exportData = response.data?.data || response.data
        setExportStatus(exportData)
        // Poll until ready
        if (exportData?.status === 'pending' || exportData?.status === 'processing') {
          pollExportStatus(exportData.id)
        }
      })
      .catch(() => setExportStatus({ status: 'failed' }))
      .finally(() => setRequestingExport(false))
  }

  function pollExportStatus(exportId, attempts = 0) {
    if (!endpoints.exportStatusPattern || attempts > 20) return
    const url = endpoints.exportStatusPattern.replace('__EXPORT__', exportId)
    window.setTimeout(() => {
      window.axios.get(url)
        .then((response) => {
          const data = response.data?.data || response.data
          setExportStatus(data)
          if (data?.status === 'pending' || data?.status === 'processing') {
            pollExportStatus(exportId, attempts + 1)
          }
        })
        .catch(() => {})
    }, 2500)
  }

  function applyLayoutPreset(presetKey) {
    updateCard({}, {
      layout: {
        layout: presetKey,
        ...(layoutPresetMap[presetKey] || {}),
      },
    })
  }

  function addDecoration(decoration) {
    const placements = ['top-left', 'top-right', 'bottom-left', 'bottom-right']
    const current = Array.isArray(card.project_json?.decorations) ? card.project_json.decorations : []
    updateCard({}, {
      decorations: [
        ...current,
        {
          key: decoration.key,
          glyph: decoration.glyph,
          placement: placements[current.length % placements.length],
          size: 28,
        },
      ].slice(0, editorOptions.validation?.max_decorations || 6),
    })
  }

  function removeDecoration(index) {
    const current = Array.isArray(card.project_json?.decorations) ? card.project_json.decorations : []
    updateCard({}, { decorations: current.filter((_, itemIndex) => itemIndex !== index) })
  }

  function togglePack(packId, bucket = 'pack_ids') {
    const current = Array.isArray(card.project_json?.assets?.[bucket]) ? card.project_json.assets[bucket] : []
    const numericId = Number(packId)
    const next = current.includes(numericId) ? current.filter((item) => item !== numericId) : [...current, numericId]
    updateCard({}, { assets: { [bucket]: next } })
  }

  function addAssetItem(item) {
    const current = Array.isArray(card.project_json?.assets?.items) ? card.project_json.assets.items : []
    updateCard({}, {
      assets: {
        items: [...current, {
          asset_key: item.key,
          label: item.label,
          glyph: item.glyph,
          type: item.type || 'glyph',
        }].slice(0, editorOptions.validation?.max_asset_items || 12),
      },
    })
  }

  function removeAssetItem(index) {
    const current = Array.isArray(card.project_json?.assets?.items) ? card.project_json.assets.items : []
    updateCard({}, { assets: { items: current.filter((_, itemIndex) => itemIndex !== index) } })
  }

  function manualSave() {
    if (!cardId) return
    setBusy(true)
    setAutosaveStatus('saving')
    window.axios.patch(apiUrl(endpoints.draftUpdatePattern, cardId), buildPayload(card, tagInput))
      .then((response) => {
        const nextCard = normalizeCard(response.data.data, editorOptions)
        setCard(nextCard)
        lastSerialized.current = JSON.stringify(buildPayload(nextCard, tagInput))
        setAutosaveStatus('saved')
        setAutosaveMessage('Draft saved')
        loadVersions(nextCard.id)
      })
      .catch(() => {
        setAutosaveStatus('error')
        setAutosaveMessage('Save failed')
      })
      .finally(() => setBusy(false))
  }

  function renderPreview() {
    if (!cardId) return
    setBusy(true)
    window.axios.post(apiUrl(endpoints.draftRenderPattern, cardId))
      .then((response) => {
        const nextCard = normalizeCard(response.data.data, editorOptions)
        setCard(nextCard)
        setAutosaveStatus('saved')
        setAutosaveMessage('Preview rendered')
      })
      .catch(() => {
        setAutosaveStatus('error')
        setAutosaveMessage('Render failed')
      })
      .finally(() => setBusy(false))
  }

  function publishCard() {
    if (!cardId) return
    setBusy(true)
    window.axios.post(apiUrl(endpoints.draftPublishPattern, cardId), buildPayload(card, tagInput))
      .then((response) => {
        const nextCard = normalizeCard(response.data.data, editorOptions)
        setCard(nextCard)
        setAutosaveStatus('saved')
        setAutosaveMessage('Card published')
        loadVersions(nextCard.id)
      })
      .catch((error) => {
        setAutosaveStatus('error')
        setAutosaveMessage(error?.response?.data?.message || 'Publish failed')
      })
      .finally(() => setBusy(false))
  }

  function deleteDraft() {
    if (!cardId || !window.confirm('Delete this draft?')) return
    setBusy(true)
    window.axios.delete(apiUrl(endpoints.draftDeletePattern, cardId))
      .then(() => {
        window.location.assign(endpoints.studioCards || '/studio/cards')
      })
      .finally(() => setBusy(false))
  }

  function uploadBackground(event) {
    const file = event.target.files?.[0]
    if (!file || !cardId) return

    const formData = new FormData()
    formData.append('background', file)

    setUploading(true)
    window.axios.post(apiUrl(endpoints.draftBackgroundPattern, cardId), formData).then((response) => {
      const nextCard = normalizeCard(response.data.data, editorOptions)
      setCard(nextCard)
      setAutosaveStatus('saved')
      setAutosaveMessage('Background uploaded')
    }).catch(() => {
      setAutosaveStatus('error')
      setAutosaveMessage('Upload failed')
    }).finally(() => setUploading(false))
  }

  function createCollection() {
    const name = window.prompt('Collection name')
    if (!name || !endpoints.collectionsStore) return
    window.axios.post(endpoints.collectionsStore, { name })
      .then(() => loadCollections())
      .catch(() => {
        setAutosaveStatus('error')
        setAutosaveMessage('Collection could not be created')
      })
  }

  function saveToCollection() {
    if (!cardId || !endpoints.savePattern) return
    setBusy(true)
    window.axios.post(apiUrl(endpoints.savePattern, cardId), {
      collection_id: selectedCollectionId ? Number(selectedCollectionId) : undefined,
    }).then((response) => {
      setCard((current) => ({ ...current, saves_count: Number(response.data?.saves_count || current.saves_count || 0) }))
      setAutosaveStatus('saved')
      setAutosaveMessage('Saved to collection')
      loadCollections()
    }).catch(() => {
      setAutosaveStatus('error')
      setAutosaveMessage('Save to collection failed')
    }).finally(() => setBusy(false))
  }

  function restoreVersion(versionId) {
    if (!cardId || !endpoints.draftRestorePattern) return
    setBusy(true)
    window.axios.post(fillPattern(endpoints.draftRestorePattern, { CARD: cardId, VERSION: versionId }))
      .then((response) => {
        const nextCard = normalizeCard(response.data.data, editorOptions)
        setCard(nextCard)
        lastSerialized.current = JSON.stringify(buildPayload(nextCard, tagInput))
        setAutosaveStatus('saved')
        setAutosaveMessage('Version restored')
        loadVersions(nextCard.id)
      })
      .catch(() => {
        setAutosaveStatus('error')
        setAutosaveMessage('Restore failed')
      })
      .finally(() => setBusy(false))
  }

  function submitChallenge(challengeId) {
    if (!cardId || !endpoints.challengeSubmitPattern) return
    setBusy(true)
    window.axios.post(fillPattern(endpoints.challengeSubmitPattern, { CHALLENGE: challengeId, CARD: cardId }))
      .then((response) => {
        setCard((current) => ({ ...current, challenge_entries_count: Number(response.data?.challenge_entries_count || current.challenge_entries_count || 0) }))
        setAutosaveStatus('saved')
        setAutosaveMessage('Submitted to challenge')
      })
      .catch((error) => {
        setAutosaveStatus('error')
        setAutosaveMessage(error?.response?.data?.message || 'Challenge submission failed')
      })
      .finally(() => setBusy(false))
  }

  const decorations = Array.isArray(card.project_json?.decorations) ? card.project_json.decorations : []
  const textBlocks = Array.isArray(card.project_json?.text_blocks) ? card.project_json.text_blocks : []
  const backgroundType = card.project_json?.background?.type || card.background_type || 'gradient'
  const assetItems = Array.isArray(card.project_json?.assets?.items) ? card.project_json.assets.items : []
  const selectedAssetPackIds = Array.isArray(card.project_json?.assets?.pack_ids) ? card.project_json.assets.pack_ids : []
  const selectedTemplatePackIds = Array.isArray(card.project_json?.assets?.template_pack_ids) ? card.project_json.assets.template_pack_ids : []
  const currentMobileStepIndex = Math.max(0, mobileSteps.findIndex((step) => step.key === currentMobileStep))
  const currentMobileStepMeta = mobileSteps[currentMobileStepIndex] || mobileSteps[0]
  const editorMode = card.editor_mode_last_used || card.project_json?.source_context?.editor_mode || 'full'
  const advancedMode = editorMode !== 'quick'
  const currentProjectSummary = summarizeProjectSnapshot(card.project_json || {})

  function sectionVisibility(stepKey) {
    return `${currentMobileStep === stepKey ? 'block' : 'hidden'} xl:block`
  }

  function goToStep(index) {
    const step = mobileSteps[index]
    if (!step) return
    setCurrentMobileStep(step.key)
    window.scrollTo({ top: 0, behavior: 'smooth' })
  }

  return (
    <StudioLayout title={previewMode ? 'Card Preview' : 'Card Editor'}>
      <Head title={previewMode ? 'Nova Card Preview' : 'Nova Card Editor'} />

      <section className="mb-6 rounded-[28px] border border-white/10 bg-[radial-gradient(circle_at_top_left,rgba(56,189,248,0.12),transparent_40%),linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.88))] p-5 shadow-[0_24px_70px_rgba(2,6,23,0.32)]">
        <div className="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
          <div>
            <p className="text-[11px] font-semibold uppercase tracking-[0.24em] text-sky-200/70">Nova Cards editor</p>
            <h2 className="mt-2 text-2xl font-semibold tracking-[-0.03em] text-white">Structured card creation with live preview and autosave.</h2>
            <div className="mt-4 flex flex-wrap items-center gap-2">
              <button type="button" onClick={() => setEditorMode('quick')} className={pillClasses(editorMode === 'quick')}>
                Quick mode
              </button>
              <button type="button" onClick={() => setEditorMode('full')} className={pillClasses(editorMode === 'full')}>
                Advanced mode
              </button>
              <span className="text-sm text-slate-300">Quick mode keeps the core card flow visible. Advanced mode unlocks layered text, fine-tuning, and deeper effects.</span>
            </div>
          </div>
          <div className="flex flex-wrap items-center gap-3">
            <NovaCardAutosaveIndicator status={autosaveStatus} message={autosaveMessage} />
            <button type="button" onClick={manualSave} disabled={busy || !cardId} className="rounded-2xl border border-white/10 bg-white/[0.05] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-white/[0.08] disabled:opacity-60">Save</button>
            <button type="button" onClick={renderPreview} disabled={busy || !cardId} className="rounded-2xl border border-amber-300/20 bg-amber-400/10 px-4 py-2.5 text-sm font-semibold text-amber-100 transition hover:bg-amber-400/15 disabled:opacity-60">Render preview</button>
            <button type="button" onClick={publishCard} disabled={busy || !cardId} className="rounded-2xl border border-emerald-300/20 bg-emerald-400/10 px-4 py-2.5 text-sm font-semibold text-emerald-100 transition hover:bg-emerald-400/15 disabled:opacity-60">Publish</button>
            {card.public_url ? <a href={card.public_url} className="rounded-2xl border border-white/10 bg-white/[0.05] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-white/[0.08]">Public page</a> : null}
          </div>
        </div>
      </section>

      <section className="mb-6 xl:hidden">
        <div className="rounded-[24px] border border-white/10 bg-white/[0.04] p-4 shadow-[0_18px_40px_rgba(2,6,23,0.18)]">
          <div className="flex gap-2 overflow-x-auto pb-2">
            {mobileSteps.map((step, index) => (
              <button key={step.key} type="button" onClick={() => goToStep(index)} className={pillClasses(currentMobileStep === step.key)}>
                {index + 1}. {step.label}
              </button>
            ))}
          </div>
          {currentMobileStepMeta ? (
            <div className="mt-3 rounded-[18px] border border-white/10 bg-[#0d1726] px-4 py-3">
              <div className="text-xs font-semibold uppercase tracking-[0.18em] text-sky-200/70">Current step</div>
              <div className="mt-1 text-base font-semibold text-white">{currentMobileStepMeta.label}</div>
              <div className="mt-1 text-sm text-slate-300">{currentMobileStepMeta.description}</div>
            </div>
          ) : null}
        </div>
      </section>

      <div className="grid gap-6 xl:grid-cols-[minmax(0,320px)_minmax(0,1fr)_minmax(0,340px)]">
        <div className="space-y-6">
          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('background')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Templates</div>
            <NovaCardTemplatePicker templates={editorOptions.templates || []} selectedId={card.template_id} onSelect={handleTemplateSelect} />
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('background')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Backgrounds</div>
            <div className="flex flex-wrap gap-2">
              {(editorOptions.background_modes || []).map((mode) => (
                <button key={mode.key} type="button" onClick={() => updateCard({ background_type: mode.key }, { background: { type: mode.key } })} className={pillClasses(backgroundType === mode.key)}>
                  {mode.label}
                </button>
              ))}
            </div>

            {(backgroundType === 'gradient' || backgroundType === 'template') ? (
              <div className="mt-4">
                <NovaCardGradientPicker gradients={editorOptions.gradient_presets || []} selectedKey={card.project_json?.background?.gradient_preset} onSelect={handleGradientSelect} />
              </div>
            ) : null}

            <div className="mt-4 grid gap-4 sm:grid-cols-2">
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Solid color</span>
                <input type="color" value={card.project_json?.background?.solid_color || '#111827'} onChange={(event) => updateCard({ background_type: 'solid' }, { background: { type: 'solid', solid_color: event.target.value } })} className="h-12 w-full rounded-2xl border border-white/10 bg-[#0d1726] p-2" />
              </label>
              {advancedMode ? <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Overlay</span>
                <select value={card.project_json?.background?.overlay_style || 'dark-soft'} onChange={(event) => updateCard({}, { background: { overlay_style: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {overlayOptions.map((option) => <option key={option.value} value={option.value}>{option.label}</option>)}
                </select>
              </label> : null}
              {advancedMode ? <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Background blur</span>
                <input type="range" min="0" max="32" step="4" value={card.project_json?.background?.blur_level || 0} onChange={(event) => updateCard({}, { background: { blur_level: Number(event.target.value) } })} className="w-full" />
              </label> : null}
              {advancedMode ? <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Overlay opacity</span>
                <input type="range" min="0" max="90" step="10" value={card.project_json?.background?.opacity || 50} onChange={(event) => updateCard({}, { background: { opacity: Number(event.target.value) } })} className="w-full" />
              </label> : null}
              {advancedMode ? <label className="block text-sm text-slate-300 sm:col-span-2">
                <span className="mb-2 block">Focal position</span>
                <select value={card.project_json?.background?.focal_position || 'center'} onChange={(event) => updateCard({}, { background: { focal_position: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.focal_positions || []).map((position) => <option key={position.key} value={position.key}>{position.label}</option>)}
                </select>
              </label> : null}
            </div>

            <div className="mt-4 rounded-[22px] border border-dashed border-white/12 bg-white/[0.03] p-4">
              <label className="flex cursor-pointer items-center justify-between gap-4 text-sm text-slate-300">
                <span>Upload background image</span>
                <span className="rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-xs font-semibold uppercase tracking-[0.16em] text-white">{uploading ? 'Uploading' : 'Choose'}</span>
                <input type="file" accept="image/png,image/jpeg,image/webp" className="hidden" onChange={uploadBackground} />
              </label>
            </div>
          </section>

          {advancedMode ? <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('background')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Decorations</div>
            <div className="grid gap-3 sm:grid-cols-2">
              {(editorOptions.decor_presets || []).map((decor) => (
                <button key={decor.key} type="button" onClick={() => addDecoration(decor)} className="flex items-center justify-between rounded-[18px] border border-white/10 bg-white/[0.03] px-4 py-3 text-left text-sm text-white transition hover:bg-white/[0.05]">
                  <span>{decor.label}</span>
                  <span className="text-lg text-sky-100">{decor.glyph}</span>
                </button>
              ))}
            </div>
            {decorations.length ? (
              <div className="mt-4 space-y-2">
                {decorations.map((decor, index) => (
                  <div key={`${decor.key}-${index}`} className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                    <span>{decor.glyph || '✦'} {decor.key}</span>
                    <button type="button" onClick={() => removeDecoration(index)} className="text-rose-200 transition hover:text-rose-100">Remove</button>
                  </div>
                ))}
              </div>
            ) : null}
          </section> : null}

          {advancedMode ? <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('background')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Official packs</div>
            <div>
              <div className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Asset packs</div>
              <div className="flex flex-wrap gap-2">
                {(editorOptions.asset_packs || []).map((pack) => (
                  <button key={`${pack.id || pack.slug}-asset`} type="button" onClick={() => pack.id && togglePack(pack.id, 'pack_ids')} className={pillClasses(pack.id ? selectedAssetPackIds.includes(Number(pack.id)) : false)}>
                    {pack.name}
                  </button>
                ))}
              </div>
            </div>
            <div className="mt-4">
              <div className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Template packs</div>
              <div className="flex flex-wrap gap-2">
                {(editorOptions.template_packs || []).map((pack) => (
                  <button key={`${pack.id || pack.slug}-template`} type="button" onClick={() => pack.id && togglePack(pack.id, 'template_pack_ids')} className={pillClasses(pack.id ? selectedTemplatePackIds.includes(Number(pack.id)) : false)}>
                    {pack.name}
                  </button>
                ))}
              </div>
            </div>

            <div className="mt-4 space-y-3">
              {(editorOptions.asset_packs || []).map((pack) => {
                const items = pack?.manifest_json?.items || []
                if (!items.length) return null

                return (
                  <div key={`${pack.id || pack.slug}-items`}>
                    <div className="mb-2 text-sm font-semibold text-white">{pack.name}</div>
                    <div className="flex flex-wrap gap-2">
                      {items.map((item) => (
                        <button key={`${pack.id || pack.slug}-${item.key}`} type="button" onClick={() => addAssetItem(item)} className="rounded-2xl border border-white/10 bg-white/[0.03] px-3 py-2 text-sm text-slate-200 transition hover:bg-white/[0.05]">
                          {item.glyph ? `${item.glyph} ` : ''}{item.label}
                        </button>
                      ))}
                    </div>
                  </div>
                )
              })}
            </div>

            {assetItems.length ? (
              <div className="mt-4 space-y-2">
                {assetItems.map((item, index) => (
                  <div key={`${item.asset_key || item.label || 'asset'}-${index}`} className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                    <span>{item.glyph ? `${item.glyph} ` : ''}{item.label || item.asset_key}</span>
                    <button type="button" onClick={() => removeAssetItem(index)} className="text-rose-200 transition hover:text-rose-100">Remove</button>
                  </div>
                ))}
              </div>
            ) : null}
          </section> : null}
        </div>

        <div className={`space-y-5 ${sectionVisibility('preview')}`}>
          <section className="rounded-[32px] border border-white/10 bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(2,6,23,0.88))] p-5 shadow-[0_24px_70px_rgba(2,6,23,0.32)]">
            <NovaCardCanvasPreview card={card} className="mx-auto max-w-[760px]" />
            {card.preview_url ? (
              <div className="mt-5 rounded-[22px] border border-white/10 bg-white/[0.03] p-3">
                <div className="mb-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">Rendered preview</div>
                <img src={card.preview_url} alt="Rendered preview" className="w-full rounded-[18px] border border-white/10 object-cover" />
              </div>
            ) : null}
          </section>
        </div>

        <div className="space-y-6">
          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('content')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Content</div>
            <div className="space-y-4">
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Title</span>
                <input value={card.title || ''} onChange={(event) => updateTextField('title', event.target.value)} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Quote text</span>
                <textarea value={card.quote_text || ''} onChange={(event) => updateTextField('quote_text', event.target.value)} rows={5} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Author</span>
                <input value={card.quote_author || ''} onChange={(event) => updateTextField('quote_author', event.target.value)} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Source</span>
                <input value={card.quote_source || ''} onChange={(event) => updateTextField('quote_source', event.target.value)} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
              </label>
            </div>

            <div className="mt-5 border-t border-white/10 pt-5">
              <div className="flex items-center justify-between gap-3">
                <div>
                  <div className="text-sm font-semibold uppercase tracking-[0.18em] text-slate-400">Text blocks</div>
                  <div className="mt-1 text-sm text-slate-300">{advancedMode ? 'Layer extra body or caption blocks without breaking legacy quote fields.' : 'Switch to advanced mode to reorder layered text blocks and add extra copy regions.'}</div>
                </div>
                {advancedMode ? <div className="flex flex-wrap gap-2">
                  <button type="button" onClick={() => addTextBlock('body')} className="rounded-2xl border border-white/10 bg-white/[0.05] px-3 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white">Add body</button>
                  <button type="button" onClick={() => addTextBlock('caption')} className="rounded-2xl border border-white/10 bg-white/[0.05] px-3 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white">Add caption</button>
                </div> : null}
              </div>

              <div className="mt-4 space-y-3">
                {textBlocks.map((block, index) => (
                  <div key={`${block.key || block.type}-${index}`} className="rounded-[20px] border border-white/10 bg-white/[0.03] p-4">
                    <div className={`grid gap-3 ${advancedMode ? 'sm:grid-cols-[42px_160px_minmax(0,1fr)_auto]' : 'sm:grid-cols-[160px_minmax(0,1fr)_auto]'} sm:items-center`}>
                      {advancedMode ? <div className="flex flex-col gap-2">
                        <button type="button" onClick={() => moveTextBlock(index, -1)} disabled={index === 0} className="rounded-xl border border-white/10 bg-white/[0.05] px-2 py-1 text-xs font-semibold text-white transition hover:bg-white/[0.08] disabled:opacity-40">Up</button>
                        <button type="button" onClick={() => moveTextBlock(index, 1)} disabled={index === textBlocks.length - 1} className="rounded-xl border border-white/10 bg-white/[0.05] px-2 py-1 text-xs font-semibold text-white transition hover:bg-white/[0.08] disabled:opacity-40">Dn</button>
                      </div> : null}
                      <select value={block.type || 'body'} onChange={(event) => updateTextBlock(index, { type: event.target.value })} className="rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-sm text-white outline-none transition focus:border-sky-300/35">
                        <option value="title">Title</option>
                        <option value="quote">Quote</option>
                        <option value="author">Author</option>
                        <option value="source">Source</option>
                        <option value="body">Body</option>
                        <option value="caption">Caption</option>
                      </select>
                      <input value={block.text || ''} onChange={(event) => updateTextBlock(index, { text: event.target.value, enabled: block.type === 'title' || block.type === 'quote' ? true : Boolean(event.target.value.trim()) })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
                      <div className="flex items-center gap-3">
                        {advancedMode ? <span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">{index + 1}</span> : null}
                        <label className="flex items-center gap-2 text-xs uppercase tracking-[0.16em] text-slate-400">
                          <input type="checkbox" checked={block.enabled !== false} onChange={(event) => updateTextBlock(index, { enabled: event.target.checked })} className="h-4 w-4 rounded border-white/20 bg-[#0d1726]" />
                          On
                        </label>
                        {advancedMode ? <button type="button" onClick={() => removeTextBlock(index)} disabled={block.type === 'title' || block.type === 'quote'} className="text-sm text-rose-200 transition hover:text-rose-100 disabled:opacity-40">Remove</button> : null}
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('style')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Typography</div>
            <NovaCardFontPicker fonts={editorOptions.font_presets || []} selectedKey={card.project_json?.typography?.font_preset} onSelect={handleFontSelect} />
            <div className="mt-4 grid gap-4 sm:grid-cols-2">
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Quote size</span>
                <input type="range" min="32" max="128" value={card.project_json?.typography?.quote_size || 72} onChange={(event) => updateCard({}, { typography: { quote_size: Number(event.target.value) } })} className="w-full" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Author size</span>
                <input type="range" min="14" max="42" value={card.project_json?.typography?.author_size || 28} onChange={(event) => updateCard({}, { typography: { author_size: Number(event.target.value) } })} className="w-full" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Text color</span>
                <input type="color" value={card.project_json?.typography?.text_color || '#ffffff'} onChange={(event) => updateCard({}, { typography: { text_color: event.target.value } })} className="h-12 w-full rounded-2xl border border-white/10 bg-[#0d1726] p-2" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Accent color</span>
                <input type="color" value={card.project_json?.typography?.accent_color || '#e0f2fe'} onChange={(event) => updateCard({}, { typography: { accent_color: event.target.value } })} className="h-12 w-full rounded-2xl border border-white/10 bg-[#0d1726] p-2" />
              </label>
              {advancedMode ? <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Letter spacing</span>
                <input type="range" min="-2" max="10" value={card.project_json?.typography?.letter_spacing || 0} onChange={(event) => updateCard({}, { typography: { letter_spacing: Number(event.target.value) } })} className="w-full" />
              </label> : null}
              {advancedMode ? <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Line height</span>
                <select value={String(card.project_json?.typography?.line_height || 1.2)} onChange={(event) => updateCard({}, { typography: { line_height: Number(event.target.value) } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.line_height_presets || []).map((preset) => <option key={preset.key} value={preset.value}>{preset.label}</option>)}
                </select>
              </label> : null}
            </div>
            {advancedMode ? <div className="mt-4 flex flex-wrap gap-2">
              {(editorOptions.shadow_presets || []).map((preset) => (
                <button key={preset.key} type="button" onClick={() => updateCard({}, { typography: { shadow_preset: preset.key } })} className={pillClasses((card.project_json?.typography?.shadow_preset || 'soft') === preset.key)}>
                  {preset.label}
                </button>
              ))}
            </div> : null}
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('format')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Format</div>
            <div className="space-y-4">
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Format</span>
                <select value={card.format || 'square'} onChange={(event) => updateCard({ format: event.target.value })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.formats || []).map((format) => <option key={format.key} value={format.key}>{format.label}</option>)}
                </select>
              </label>
            </div>
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('style')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Layout</div>
            <div className="space-y-4">
              <div>
                <span className="mb-2 block text-sm text-slate-300">Layout preset</span>
                <div className="flex flex-wrap gap-2">
                  {(editorOptions.layout_presets || []).map((preset) => (
                    <button key={preset.key} type="button" onClick={() => applyLayoutPreset(preset.key)} className={pillClasses((card.project_json?.layout?.layout || 'quote_heavy') === preset.key)}>
                      {preset.label}
                    </button>
                  ))}
                </div>
              </div>

              {advancedMode ? <div className="grid gap-4 sm:grid-cols-2">
                <label className="block text-sm text-slate-300">
                  <span className="mb-2 block">Alignment</span>
                  <select value={card.project_json?.layout?.alignment || 'center'} onChange={(event) => updateCard({}, { layout: { alignment: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                    {(editorOptions.alignment_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                  </select>
                </label>
                <label className="block text-sm text-slate-300">
                  <span className="mb-2 block">Vertical position</span>
                  <select value={card.project_json?.layout?.position || 'center'} onChange={(event) => updateCard({}, { layout: { position: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                    {(editorOptions.position_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                  </select>
                </label>
                <label className="block text-sm text-slate-300">
                  <span className="mb-2 block">Padding</span>
                  <select value={card.project_json?.layout?.padding || 'comfortable'} onChange={(event) => updateCard({}, { layout: { padding: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                    {(editorOptions.padding_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                  </select>
                </label>
                <label className="block text-sm text-slate-300">
                  <span className="mb-2 block">Text width</span>
                  <select value={card.project_json?.layout?.max_width || 'balanced'} onChange={(event) => updateCard({}, { layout: { max_width: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                    {(editorOptions.max_width_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                  </select>
                </label>
              </div> : <p className="text-sm text-slate-300">Advanced mode exposes alignment, spacing, and width controls when you need layout precision.</p>}
            </div>
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('publish')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Publish settings</div>
            <div className="space-y-4">
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Category</span>
                <select value={card.category_id || ''} onChange={(event) => updateCard({ category_id: event.target.value ? Number(event.target.value) : null })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  <option value="">Select category</option>
                  {(editorOptions.categories || []).map((category) => <option key={category.id} value={category.id}>{category.name}</option>)}
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Visibility</span>
                <select value={card.visibility || 'private'} onChange={(event) => updateCard({ visibility: event.target.value })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  <option value="private">Private</option>
                  <option value="unlisted">Unlisted</option>
                  <option value="public">Public</option>
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Tags</span>
                <input value={tagInput} onChange={(event) => setTagInput(event.target.value)} placeholder="motivation, calm, poetry" className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
              </label>
              <label className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                <span>Allow download</span>
                <input type="checkbox" checked={Boolean(card.allow_download)} onChange={(event) => updateCard({ allow_download: event.target.checked })} className="h-4 w-4 rounded border-white/20 bg-[#0d1726]" />
              </label>
              <label className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                <span>Allow remix</span>
                <input type="checkbox" checked={Boolean(card.allow_remix)} onChange={(event) => updateCard({ allow_remix: event.target.checked })} className="h-4 w-4 rounded border-white/20 bg-[#0d1726]" />
              </label>
              <label className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                <span>Allow export</span>
                <input type="checkbox" checked={Boolean(card.allow_export !== false)} onChange={(event) => updateCard({ allow_export: event.target.checked })} className="h-4 w-4 rounded border-white/20 bg-[#0d1726]" />
              </label>
              <label className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                <span>Allow background reuse</span>
                <input type="checkbox" checked={Boolean(card.allow_background_reuse)} onChange={(event) => updateCard({ allow_background_reuse: event.target.checked })} className="h-4 w-4 rounded border-white/20 bg-[#0d1726]" />
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Style family</span>
                <select value={card.style_family || ''} onChange={(event) => updateCard({ style_family: event.target.value || null })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  <option value="">None</option>
                  {(editorOptions.style_families || []).map((sf) => <option key={sf.key} value={sf.key}>{sf.label}</option>)}
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Description</span>
                <textarea value={card.description || ''} onChange={(event) => updateCard({ description: event.target.value })} rows={4} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35" />
              </label>
            </div>
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('publish')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Collections & challenges</div>
            <div className="space-y-4">
              <div>
                <span className="mb-2 block text-sm text-slate-300">Save to collection</span>
                <div className="flex gap-3">
                  <select value={selectedCollectionId} onChange={(event) => setSelectedCollectionId(event.target.value)} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                    <option value="">Default saved cards</option>
                    {collections.map((collection) => <option key={collection.id} value={collection.id}>{collection.name}</option>)}
                  </select>
                  <button type="button" onClick={saveToCollection} disabled={!cardId || busy} className="rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-3 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15 disabled:opacity-60">Save</button>
                </div>
                <button type="button" onClick={createCollection} className="mt-2 text-sm text-slate-300 transition hover:text-white">Create collection</button>
              </div>

              <div>
                <span className="mb-2 block text-sm text-slate-300">Challenge entry</span>
                <div className="space-y-2">
                  {(editorOptions.challenge_feed || []).slice(0, 4).map((challenge) => (
                    <button key={challenge.id} type="button" onClick={() => submitChallenge(challenge.id)} disabled={!cardId || busy} className="flex w-full items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-left text-sm text-slate-200 transition hover:bg-white/[0.05] disabled:opacity-60">
                      <span>{challenge.title}</span>
                      <span className="text-xs uppercase tracking-[0.16em] text-slate-400">{challenge.status}</span>
                    </button>
                  ))}
                </div>
              </div>
            </div>
          </section>

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('publish')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Version history</div>
            <div className="space-y-2">
              {versions.length ? versions.map((version) => (
                <div key={version.id} className="flex items-center justify-between rounded-2xl border border-white/10 bg-white/[0.03] px-4 py-3 text-sm text-slate-200">
                  <div className="min-w-0 flex-1 pr-4">
                    <div className="font-semibold text-white">Version {version.version_number}</div>
                    <div className="text-xs text-slate-400">{version.label || 'Autosaved snapshot'}{version.created_at ? ` • ${new Date(version.created_at).toLocaleString()}` : ''}</div>
                    <div className="mt-3 rounded-[18px] border border-white/10 bg-[#0d1726] px-3 py-3">
                      <div className="text-sm font-semibold text-white">{summarizeProjectSnapshot(version.snapshot_json || {}).title || currentProjectSummary.title}</div>
                      <div className="mt-1 text-sm text-slate-300">{summarizeProjectSnapshot(version.snapshot_json || {}).quote || 'Snapshot available for compare.'}</div>
                      <div className="mt-2 flex flex-wrap gap-2 text-[11px] font-semibold uppercase tracking-[0.14em] text-slate-400">
                        <span className="rounded-full border border-white/10 bg-white/[0.04] px-2 py-1">Blocks {summarizeProjectSnapshot(version.snapshot_json || {}).enabledBlocks}/{summarizeProjectSnapshot(version.snapshot_json || {}).blockCount}</span>
                        <span className="rounded-full border border-white/10 bg-white/[0.04] px-2 py-1">{summarizeProjectSnapshot(version.snapshot_json || {}).layout.replace(/_/g, ' ')}</span>
                        <span className="rounded-full border border-white/10 bg-white/[0.04] px-2 py-1">{summarizeProjectSnapshot(version.snapshot_json || {}).font.replace(/-/g, ' ')}</span>
                      </div>
                      <div className="mt-3 flex flex-wrap gap-2 text-[11px] font-semibold uppercase tracking-[0.14em] text-sky-100/80">
                        {compareProjectSnapshots(card.project_json || {}, version.snapshot_json || {}).map((item) => (
                          <span key={`${version.id}-${item}`} className="rounded-full border border-sky-300/15 bg-sky-400/10 px-2 py-1">{item}</span>
                        ))}
                      </div>
                    </div>
                  </div>
                  <button type="button" onClick={() => restoreVersion(version.id)} disabled={busy || !cardId} className="rounded-2xl border border-white/10 bg-white/[0.05] px-3 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white transition hover:bg-white/[0.08] disabled:opacity-60">Restore</button>
                </div>
              )) : <div className="rounded-2xl border border-dashed border-white/12 bg-white/[0.03] px-4 py-5 text-sm text-slate-400">Versions appear here after the first saved snapshot.</div>}
            </div>
          </section>

          {advancedMode ? <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('style')}`}>
            <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Frame &amp; Effects</div>
            <div className="grid gap-4 sm:grid-cols-2">
              <label className="block text-sm text-slate-300 sm:col-span-2">
                <span className="mb-2 block">Frame</span>
                <select value={card.project_json?.frame?.preset || 'none'} onChange={(event) => updateCard({}, { frame: { preset: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.frame_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Color grade</span>
                <select value={card.project_json?.effects?.color_grade || 'none'} onChange={(event) => updateCard({}, { effects: { color_grade: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.color_grade_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Effect</span>
                <select value={card.project_json?.effects?.effect_preset || 'none'} onChange={(event) => updateCard({}, { effects: { effect_preset: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.effect_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Quote mark style</span>
                <select value={card.project_json?.typography?.quote_mark_preset || 'none'} onChange={(event) => updateCard({}, { typography: { quote_mark_preset: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.quote_mark_presets || []).map((preset) => <option key={preset.key} value={preset.key}>{preset.label}</option>)}
                </select>
              </label>
              <label className="block text-sm text-slate-300">
                <span className="mb-2 block">Text panel style</span>
                <select value={card.project_json?.typography?.text_panel_style || 'none'} onChange={(event) => updateCard({}, { typography: { text_panel_style: event.target.value } })} className="w-full rounded-2xl border border-white/10 bg-[#0d1726] px-4 py-3 text-white outline-none transition focus:border-sky-300/35">
                  {(editorOptions.text_panel_styles || []).map((style) => <option key={style.key} value={style.key}>{style.label}</option>)}
                </select>
              </label>
            </div>
          </section> : null}

          {advancedMode && (Object.keys(creatorPresets).length > 0 || endpoints.presetsIndex) ? (
            <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('style')}`}>
              <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Creator presets</div>
              <NovaCardPresetPicker
                presets={creatorPresets}
                endpoints={endpoints}
                cardId={cardId}
                onApplyPatch={handleApplyPresetPatch}
                onPresetsChange={reloadPresets}
              />
            </section>
          ) : null}

          {advancedMode && endpoints.aiSuggestPattern ? (
            <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('style')}`}>
              <div className="mb-4 flex items-center justify-between">
                <div className="text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">AI assist</div>
                <button
                  type="button"
                  disabled={loadingAi || !cardId}
                  onClick={fetchAiSuggestions}
                  className="rounded-full border border-sky-300/20 bg-sky-400/10 px-3 py-1.5 text-xs font-semibold text-sky-200 transition hover:bg-sky-400/15 disabled:opacity-50"
                >
                  {loadingAi ? 'Analysing…' : 'Suggest'}
                </button>
              </div>
              {aiSuggestions ? (
                <div className="space-y-4">
                  {aiSuggestions.tags?.length > 0 && (
                    <div>
                      <div className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-slate-500">Suggested tags</div>
                      <div className="flex flex-wrap gap-2">
                        {aiSuggestions.tags.map((tag) => (
                          <button key={tag} type="button" onClick={() => applyAiTagSuggestions([tag])} className="rounded-full border border-sky-400/20 bg-sky-400/10 px-3 py-1 text-xs font-semibold text-sky-200 transition hover:bg-sky-400/15">
                            + {tag}
                          </button>
                        ))}
                      </div>
                      <button type="button" onClick={() => applyAiTagSuggestions(aiSuggestions.tags)} className="mt-2 text-xs text-slate-400 underline transition hover:text-white">
                        Add all
                      </button>
                    </div>
                  )}
                  {aiSuggestions.mood && (
                    <div className="flex items-center gap-3 rounded-xl border border-white/10 bg-white/[0.03] px-3 py-2.5">
                      <i className="fa-solid fa-wand-magic-sparkles text-sky-300 text-xs" />
                      <div>
                        <div className="text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500">Mood</div>
                        <div className="text-sm text-white">{aiSuggestions.mood}</div>
                      </div>
                    </div>
                  )}
                  {aiSuggestions.layout_suggestion && (
                    <div className="flex items-center gap-3 rounded-xl border border-white/10 bg-white/[0.03] px-3 py-2.5">
                      <i className="fa-solid fa-table-columns text-sky-300 text-xs" />
                      <div>
                        <div className="text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500">Layout suggestion</div>
                        <div className="text-sm text-white">{aiSuggestions.layout_suggestion}</div>
                      </div>
                      <button type="button" onClick={() => updateCard({}, { layout: { layout: aiSuggestions.layout_suggestion } })} className="ml-auto rounded-full border border-white/10 bg-white/[0.05] px-3 py-1 text-xs font-semibold text-white transition hover:bg-white/[0.08]">
                        Apply
                      </button>
                    </div>
                  )}
                  {(aiSuggestions.readability_fixes || []).map((fix, fi) => (
                    <div key={fi} className="flex items-start gap-3 rounded-xl border border-amber-400/15 bg-amber-400/[0.06] px-3 py-2.5">
                      <i className="fa-solid fa-triangle-exclamation text-amber-300 text-xs mt-0.5" />
                      <div className="text-sm text-amber-100">{fix}</div>
                    </div>
                  ))}
                </div>
              ) : (
                <p className="text-sm text-slate-500">Run a suggestion pass to see AI-powered tips for this card.</p>
              )}
            </section>
          ) : null}

          {endpoints.exportPattern ? (
            <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('preview')}`}>
              <div className="mb-4 text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Export</div>
              <div className="flex flex-wrap gap-2">
                {(editorOptions.export_formats || []).map((fmt) => (
                  <button
                    key={fmt.key}
                    type="button"
                    disabled={requestingExport || !cardId}
                    onClick={() => requestExport(fmt.key)}
                    className={`rounded-full border px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.16em] transition disabled:opacity-50 ${activeExportType === fmt.key && exportStatus ? 'border-sky-300/30 bg-sky-400/15 text-sky-100' : 'border-white/10 bg-white/[0.03] text-slate-300 hover:bg-white/[0.05]'}`}
                  >
                    {fmt.label}
                  </button>
                ))}
              </div>
              {exportStatus && (
                <div className="mt-3 rounded-[18px] border border-white/10 bg-white/[0.03] p-4">
                  <div className="flex items-center gap-3">
                    <i className={`fa-solid text-sm ${exportStatus.status === 'ready' ? 'fa-check text-emerald-300' : exportStatus.status === 'failed' ? 'fa-triangle-exclamation text-rose-300' : 'fa-rotate fa-spin text-sky-300'}`} />
                    <div>
                      <div className="text-xs font-semibold uppercase tracking-[0.18em] text-slate-400">Export status</div>
                      <div className="text-sm font-semibold text-white capitalize">{exportStatus.status}</div>
                    </div>
                    {exportStatus.status === 'ready' && exportStatus.output_url && (
                      <a href={exportStatus.output_url} download className="ml-auto rounded-full border border-emerald-300/20 bg-emerald-400/10 px-3 py-1.5 text-xs font-semibold text-emerald-200 transition hover:bg-emerald-400/15">
                        Download
                      </a>
                    )}
                  </div>
                </div>
              )}
            </section>
          ) : null}

          <section className={`rounded-[28px] border border-white/10 bg-white/[0.04] p-5 ${sectionVisibility('publish')}`}>
            <div className="flex items-center justify-between gap-3">
              <div>
                <div className="text-sm font-semibold uppercase tracking-[0.2em] text-slate-400">Draft actions</div>
                <div className="mt-2 text-sm text-slate-300">Preview route and delete controls for draft cleanup.</div>
                {card.lineage?.original_card ? <div className="mt-2 text-xs uppercase tracking-[0.16em] text-sky-200/70">Remix lineage: {card.lineage.original_card.title}</div> : null}
              </div>
              <div className="flex flex-wrap gap-3">
                {cardId ? <Link href={(endpoints.studioCards || '/studio/cards')}>Back</Link> : null}
                <button type="button" onClick={deleteDraft} disabled={busy || !cardId} className="rounded-2xl border border-rose-300/20 bg-rose-400/10 px-4 py-2.5 text-sm font-semibold text-rose-100 transition hover:bg-rose-400/15 disabled:opacity-60">Delete draft</button>
              </div>
            </div>
          </section>
        </div>
      </div>

      <section className="sticky bottom-0 z-20 mt-6 border-t border-white/10 bg-[rgba(2,6,23,0.92)] px-4 py-3 backdrop-blur xl:hidden">
        <div className="mx-auto flex max-w-7xl items-center justify-between gap-3">
          <button type="button" onClick={() => goToStep(currentMobileStepIndex - 1)} disabled={currentMobileStepIndex === 0} className="rounded-2xl border border-white/10 bg-white/[0.05] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-white/[0.08] disabled:opacity-50">
            Back
          </button>
          <div className="text-center">
            <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500">Step {currentMobileStepIndex + 1} / {mobileSteps.length}</div>
            <div className="mt-1 text-sm font-semibold text-white">{currentMobileStepMeta?.label}</div>
          </div>
          <button type="button" onClick={() => goToStep(currentMobileStepIndex + 1)} disabled={currentMobileStepIndex >= mobileSteps.length - 1} className="rounded-2xl border border-sky-300/20 bg-sky-400/10 px-4 py-2.5 text-sm font-semibold text-sky-100 transition hover:bg-sky-400/15 disabled:opacity-50">
            Next
          </button>
        </div>
      </section>
    </StudioLayout>
  )
}
