import React from 'react'
import NovaSelect from '../ui/NovaSelect'

const TYPE_LABELS = {
  style: 'Style',
  layout: 'Layout',
  background: 'Background',
  typography: 'Typography',
  starter: 'Starter',
}

const TYPE_ICONS = {
  style: 'fa-palette',
  layout: 'fa-table-columns',
  background: 'fa-image',
  typography: 'fa-font',
  starter: 'fa-star',
}

function PresetCard({ preset, onApply, onDelete, applying }) {
  return (
    <div className="group relative flex items-center gap-3 rounded-[18px] border border-white/10 bg-white/[0.03] px-3.5 py-3 transition hover:border-white/20 hover:bg-white/[0.05]">
      <button
        type="button"
        disabled={applying}
        onClick={() => onApply(preset)}
        className="flex flex-1 items-center gap-3 text-left"
      >
        <span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full border border-white/10 bg-white/[0.06] text-sky-300 text-xs">
          <i className={`fa-solid ${TYPE_ICONS[preset.preset_type] || 'fa-sparkles'}`} />
        </span>
        <span className="flex-1 min-w-0">
          <span className="block truncate text-sm font-semibold text-white">{preset.name}</span>
          <span className="block text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500">
            {TYPE_LABELS[preset.preset_type] || preset.preset_type}
            {preset.is_default ? ' · Default' : ''}
          </span>
        </span>
        {applying ? (
          <i className="fa-solid fa-rotate fa-spin text-sky-300 text-xs" />
        ) : (
          <i className="fa-solid fa-chevron-right text-slate-500 text-xs opacity-0 transition group-hover:opacity-100" />
        )}
      </button>
      <button
        type="button"
        onClick={() => onDelete(preset)}
        className="ml-1 rounded-full p-1.5 text-slate-500 opacity-0 transition hover:text-rose-400 group-hover:opacity-100"
        title="Delete preset"
      >
        <i className="fa-solid fa-trash-can text-xs" />
      </button>
    </div>
  )
}

export default function NovaCardPresetPicker({
  presets = {},
  endpoints = {},
  cardId = null,
  onApplyPatch,
  onPresetsChange,
  activeType = null,
}) {
  const [selectedType, setSelectedType] = React.useState(activeType || 'style')
  const [applyingId, setApplyingId] = React.useState(null)
  const [capturing, setCapturing] = React.useState(false)
  const [captureName, setCaptureName] = React.useState('')
  const [captureType, setCaptureType] = React.useState('style')
  const [showCaptureForm, setShowCaptureForm] = React.useState(false)
  const [error, setError] = React.useState(null)

  const typeKeys = Object.keys(TYPE_LABELS)
  const listedPresets = Array.isArray(presets[selectedType]) ? presets[selectedType] : []

  async function handleApply(preset) {
    if (!cardId || !endpoints.presetApplyPattern) return
    const url = endpoints.presetApplyPattern
      .replace('__PRESET__', preset.id)
      .replace('__CARD__', cardId)

    setApplyingId(preset.id)
    setError(null)

    try {
      const res = await fetch(url, {
        method: 'GET',
        headers: { 'X-Requested-With': 'XMLHttpRequest', Accept: 'application/json' },
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data?.message || 'Failed to apply preset')
      if (data?.project_patch && onApplyPatch) {
        onApplyPatch(data.project_patch)
      }
    } catch (err) {
      setError(err.message || 'Failed to apply preset')
    } finally {
      setApplyingId(null)
    }
  }

  async function handleDelete(preset) {
    if (!endpoints.presetDestroyPattern) return
    const url = endpoints.presetDestroyPattern.replace('__PRESET__', preset.id)

    if (!window.confirm(`Delete preset "${preset.name}"?`)) return

    try {
      const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || ''
      const res = await fetch(url, {
        method: 'DELETE',
        headers: {
          'X-Requested-With': 'XMLHttpRequest',
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken,
        },
      })
      if (!res.ok) throw new Error('Failed to delete preset')
      onPresetsChange?.()
    } catch (err) {
      setError(err.message || 'Failed to delete preset')
    }
  }

  async function handleCapture(e) {
    e.preventDefault()
    if (!cardId || !endpoints.capturePresetPattern || !captureName.trim()) return
    const url = endpoints.capturePresetPattern.replace('__CARD__', cardId)

    setCapturing(true)
    setError(null)

    try {
      const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || ''
      const res = await fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken,
        },
        body: JSON.stringify({ name: captureName.trim(), preset_type: captureType }),
      })
      const data = await res.json()
      if (!res.ok) throw new Error(data?.message || 'Failed to capture preset')
      setCaptureName('')
      setShowCaptureForm(false)
      onPresetsChange?.()
    } catch (err) {
      setError(err.message || 'Failed to capture preset')
    } finally {
      setCapturing(false)
    }
  }

  return (
    <div className="flex flex-col gap-4">
      {/* Type tabs */}
      <div className="flex flex-wrap gap-2">
        {typeKeys.map((type) => (
          <button
            key={type}
            type="button"
            onClick={() => setSelectedType(type)}
            className={`rounded-full border px-3 py-1.5 text-xs font-semibold uppercase tracking-[0.16em] transition ${
              selectedType === type
                ? '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]'
            }`}
          >
            <i className={`fa-solid ${TYPE_ICONS[type]} mr-1.5`} />
            {TYPE_LABELS[type]}
            {Array.isArray(presets[type]) && presets[type].length > 0 && (
              <span className="ml-1.5 rounded-full bg-white/10 px-1.5 text-[10px]">{presets[type].length}</span>
            )}
          </button>
        ))}
      </div>

      {/* Preset list */}
      {listedPresets.length > 0 ? (
        <div className="flex flex-col gap-2">
          {listedPresets.map((preset) => (
            <PresetCard
              key={preset.id}
              preset={preset}
              applying={applyingId === preset.id}
              onApply={handleApply}
              onDelete={handleDelete}
            />
          ))}
        </div>
      ) : (
        <p className="text-sm text-slate-500">No {TYPE_LABELS[selectedType]?.toLowerCase()} presets saved yet.</p>
      )}

      {/* Capture from current card */}
      {cardId && endpoints.capturePresetPattern && (
        <div className="mt-1 border-t border-white/[0.06] pt-3">
          {showCaptureForm ? (
            <form onSubmit={handleCapture} className="flex flex-col gap-2">
              <input
                type="text"
                value={captureName}
                onChange={(e) => setCaptureName(e.target.value)}
                placeholder="Preset name…"
                maxLength={64}
                required
                className="w-full rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2 text-sm text-white placeholder-slate-500 outline-none focus:border-sky-400/40"
              />
              <NovaSelect
                value={captureType}
                onChange={(value) => setCaptureType(value)}
                options={typeKeys.map((type) => ({ value: type, label: TYPE_LABELS[type] }))}
                searchable={false}
              />
              <div className="flex gap-2">
                <button
                  type="submit"
                  disabled={capturing || !captureName.trim()}
                  className="flex-1 rounded-xl bg-sky-500/20 py-2 text-sm font-semibold text-sky-200 transition hover:bg-sky-500/30 disabled:opacity-50"
                >
                  {capturing ? 'Saving…' : 'Save preset'}
                </button>
                <button
                  type="button"
                  onClick={() => setShowCaptureForm(false)}
                  className="rounded-xl border border-white/10 px-4 py-2 text-sm text-slate-400 transition hover:bg-white/[0.05]"
                >
                  Cancel
                </button>
              </div>
            </form>
          ) : (
            <button
              type="button"
              onClick={() => setShowCaptureForm(true)}
              className="flex w-full items-center gap-2 rounded-xl border border-dashed border-white/15 px-3 py-2.5 text-sm text-slate-400 transition hover:border-white/25 hover:text-slate-200"
            >
              <i className="fa-solid fa-plus text-xs" />
              Capture current as preset
            </button>
          )}
        </div>
      )}

      {error && (
        <p className="rounded-xl border border-rose-400/20 bg-rose-400/10 px-3 py-2 text-xs text-rose-300">{error}</p>
      )}
    </div>
  )
}
