import { useState, useEffect } from 'react'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import {
  Save, Plus, Trash2, ChevronUp, ChevronDown,
  GripVertical, Eye, EyeOff, ToggleLeft, ToggleRight,
} from 'lucide-react'
import api from '../../api/client'

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

type Visibility = 'required' | 'optional' | 'hidden'

interface StdField {
  key: string
  label: string
  visibility: Visibility
}

interface CompPair {
  component_type: string
  required: boolean
}

interface Template {
  id: string
  name: string
  category_key: string
  description?: string | null
  is_active: boolean
  standard_fields: any
  component_schema: any
}

// ---------------------------------------------------------------------------
// All canonical standard field definitions (maps to DB columns in order_items)
// ---------------------------------------------------------------------------

const ALL_FIELD_DEFS: { key: string; defaultLabel: string }[] = [
  { key: 'ebene1',                defaultLabel: 'Ebene 1' },
  { key: 'ebene2',                defaultLabel: 'Ebene 2' },
  { key: 'baureihe',              defaultLabel: 'Baureihe' },
  { key: 'pim_id',                defaultLabel: 'PIM-ID' },
  { key: 'produkt_baureihe',      defaultLabel: 'Produkt / Baureihe' },
  { key: 'gewaehltes_produkt',    defaultLabel: 'Gewähltes Produkt' },
  { key: 'name_cad_modell',       defaultLabel: 'Name CAD-Modell' },
  { key: 'gewuenschte_bildnummer',defaultLabel: 'Gewünschte Bildnummer' },
  { key: 'lagertyp',              defaultLabel: 'Lagertyp' },
  { key: 'medias_rendering',      defaultLabel: 'Medias Rendering' },
]

// ---------------------------------------------------------------------------
// Normalisation helpers
// ---------------------------------------------------------------------------

function normalizeFields(raw: any): StdField[] {
  // New array format: [{key, label, visibility}]
  if (Array.isArray(raw) && raw.length > 0 && raw[0].key) {
    const existing = new Map(raw.map((f: StdField) => [f.key, f]))
    // Preserve saved order, then append any missing canonical fields
    const ordered: StdField[] = raw.filter((f: StdField) =>
      ALL_FIELD_DEFS.some((d) => d.key === f.key),
    )
    ALL_FIELD_DEFS.forEach(({ key, defaultLabel }) => {
      if (!existing.has(key)) {
        ordered.push({ key, label: defaultLabel, visibility: 'optional' })
      }
    })
    return ordered
  }
  // Legacy dict format {"0": {label, required}} or empty — use canonical defaults
  return ALL_FIELD_DEFS.map(({ key, defaultLabel }) => ({
    key,
    label: defaultLabel,
    visibility: 'optional' as Visibility,
  }))
}

function normalizePairs(raw: any): CompPair[] {
  if (!raw) return []
  if (Array.isArray(raw.pairs)) return raw.pairs.map((p: any) => ({
    component_type: p.component_type ?? p.part_name ?? '',
    required: p.required ?? false,
  }))
  if (Array.isArray(raw)) return raw.map((p: any) => ({
    component_type: p.component_type ?? p.part_name ?? '',
    required: p.required ?? false,
  }))
  return []
}

// ---------------------------------------------------------------------------
// Small helpers
// ---------------------------------------------------------------------------

function moveItem<T>(arr: T[], from: number, to: number): T[] {
  const next = [...arr]
  const [item] = next.splice(from, 1)
  next.splice(to, 0, item)
  return next
}

const VIS_STYLES: Record<Visibility, string> = {
  required: 'bg-accent text-white',
  optional: 'bg-blue-500 text-white',
  hidden:   'bg-surface-muted text-content-secondary',
}

function VisibilityToggle({
  value,
  onChange,
}: {
  value: Visibility
  onChange: (v: Visibility) => void
}) {
  const cycle: Visibility[] = ['required', 'optional', 'hidden']
  const labels: Record<Visibility, string> = { required: 'Required', optional: 'Optional', hidden: 'Hidden' }
  return (
    <button
      type="button"
      onClick={() => onChange(cycle[(cycle.indexOf(value) + 1) % 3])}
      className={`px-2.5 py-1 rounded text-xs font-medium transition-colors ${VIS_STYLES[value]}`}
      title="Click to cycle: Required → Optional → Hidden"
    >
      {labels[value]}
    </button>
  )
}

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------

export default function TemplateEditor({
  template,
  onClose,
}: {
  template: Template
  onClose: () => void
}) {
  const qc = useQueryClient()

  const [name, setName] = useState(template.name)
  const [description, setDescription] = useState(template.description ?? '')
  const [isActive, setIsActive] = useState(template.is_active)
  const [fields, setFields] = useState<StdField[]>(() => normalizeFields(template.standard_fields))
  const [pairs, setPairs] = useState<CompPair[]>(() => normalizePairs(template.component_schema))
  const [showHidden, setShowHidden] = useState(false)
  const [newFieldKey, setNewFieldKey] = useState('')

  useEffect(() => {
    setName(template.name)
    setDescription(template.description ?? '')
    setIsActive(template.is_active)
    setFields(normalizeFields(template.standard_fields))
    setPairs(normalizePairs(template.component_schema))
  }, [template.id]) // eslint-disable-line react-hooks/exhaustive-deps

  const saveMut = useMutation({
    mutationFn: () =>
      api.patch(`/templates/${template.id}`, {
        name,
        description: description || null,
        is_active: isActive,
        standard_fields: fields,
        component_schema: { pairs },
      }),
    onSuccess: () => {
      toast.success('Template saved')
      qc.invalidateQueries({ queryKey: ['admin-templates'] })
      qc.invalidateQueries({ queryKey: ['templates'] })
    },
    onError: (e: any) => toast.error(e.response?.data?.detail || 'Failed to save'),
  })

  // ---- Standard fields helpers ----
  function updateField(i: number, patch: Partial<StdField>) {
    setFields((f) => f.map((x, j) => (j === i ? { ...x, ...patch } : x)))
  }
  function removeField(i: number) {
    // Don't delete — mark hidden so it stays in DB but hidden in UI
    updateField(i, { visibility: 'hidden' })
  }
  const hiddenKeys = new Set(fields.filter((f) => f.visibility === 'hidden').map((f) => f.key))
  const availableToAdd = ALL_FIELD_DEFS.filter((d) => hiddenKeys.has(d.key))

  function restoreField(key: string) {
    setFields((f) =>
      f.map((x) => (x.key === key ? { ...x, visibility: 'optional' } : x)),
    )
    setNewFieldKey('')
  }

  // ---- Component pair helpers ----
  function updatePair(i: number, patch: Partial<CompPair>) {
    setPairs((p) => p.map((x, j) => (j === i ? { ...x, ...patch } : x)))
  }
  function addPair() {
    setPairs((p) => [...p, { component_type: '', required: false }])
  }
  function removePair(i: number) {
    setPairs((p) => p.filter((_, j) => j !== i))
  }

  // ---- Visible fields for rendering ----
  const visibleFields = showHidden ? fields : fields.filter((f) => f.visibility !== 'hidden')

  // ---- Shared styles ----
  const ROW = 'flex items-center gap-2 px-3 py-2 rounded-lg border border-border-light bg-surface-alt group'
  const ICON_BTN = 'p-1 rounded text-content-muted hover:text-content-secondary hover:bg-surface transition-colors disabled:opacity-30'
  const INPUT = 'flex-1 min-w-0 text-sm bg-transparent border-b border-transparent focus:border-accent focus:outline-none py-0.5 text-content'

  return (
    <div className="border border-border-default rounded-xl bg-surface shadow-sm">
      {/* ------------------------------------------------------------------ */}
      {/* Header                                                              */}
      {/* ------------------------------------------------------------------ */}
      <div className="flex items-center justify-between px-5 py-4 border-b border-border-default bg-surface-alt rounded-t-xl gap-4">
        <div className="flex-1 min-w-0 space-y-1.5">
          {/* Editable name */}
          <input
            value={name}
            onChange={(e) => setName(e.target.value)}
            className="text-base font-semibold text-content bg-transparent border-b border-transparent focus:border-accent focus:outline-none w-full"
            placeholder="Template name"
          />
          {/* Category key (read-only) + active toggle */}
          <div className="flex items-center gap-3">
            <span className="text-xs text-content-muted font-mono">{template.category_key}</span>
            <button
              type="button"
              onClick={() => setIsActive((v) => !v)}
              className={`inline-flex items-center gap-1.5 text-xs font-medium px-2 py-0.5 rounded-full transition-colors ${
                isActive ? 'bg-status-success-bg text-status-success-text' : 'bg-surface-muted text-content-muted'
              }`}
            >
              {isActive ? <ToggleRight size={13} /> : <ToggleLeft size={13} />}
              {isActive ? 'Active' : 'Inactive'}
            </button>
          </div>
          {/* Description */}
          <input
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            className="text-xs text-content-muted bg-transparent border-b border-transparent focus:border-accent focus:outline-none w-full"
            placeholder="Description (optional)"
          />
        </div>
        <div className="flex items-center gap-2 shrink-0">
          <button
            onClick={() => saveMut.mutate()}
            disabled={saveMut.isPending}
            className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-accent hover:bg-accent-hover disabled:opacity-50 text-white text-sm font-medium transition-colors"
          >
            <Save size={14} />
            {saveMut.isPending ? 'Saving…' : 'Save'}
          </button>
        </div>
      </div>

      <div className="p-5 space-y-8">
        {/* ---------------------------------------------------------------- */}
        {/* Standard Fields                                                   */}
        {/* ---------------------------------------------------------------- */}
        <section>
          <div className="flex items-center justify-between mb-3">
            <div>
              <h3 className="text-sm font-semibold text-content-secondary uppercase tracking-wide">
                Standard Fields
              </h3>
              <p className="text-xs text-content-muted mt-0.5">
                Rename, reorder, and set visibility for each column. Hidden fields are excluded from forms.
              </p>
            </div>
            <button
              type="button"
              onClick={() => setShowHidden((v) => !v)}
              className="inline-flex items-center gap-1.5 text-xs text-content-muted hover:text-content px-2 py-1 rounded border border-border-default hover:bg-surface-hover transition-colors"
            >
              {showHidden ? <EyeOff size={12} /> : <Eye size={12} />}
              {showHidden ? 'Hide hidden' : `Show hidden (${hiddenKeys.size})`}
            </button>
          </div>

          <div className="space-y-1.5">
            {visibleFields.map((field, i) => {
              // Real index in fields array (needed for moveItem / updateField)
              const realIdx = fields.indexOf(field)
              const isHidden = field.visibility === 'hidden'
              return (
                <div
                  key={field.key}
                  className={`${ROW} ${isHidden ? 'opacity-50' : ''}`}
                >
                  {/* Reorder */}
                  <div className="flex flex-col gap-0.5 shrink-0">
                    <button
                      type="button"
                      className={ICON_BTN}
                      disabled={realIdx === 0}
                      onClick={() => setFields((f) => moveItem(f, realIdx, realIdx - 1))}
                      aria-label="Move up"
                    >
                      <ChevronUp size={12} />
                    </button>
                    <button
                      type="button"
                      className={ICON_BTN}
                      disabled={realIdx === fields.length - 1}
                      onClick={() => setFields((f) => moveItem(f, realIdx, realIdx + 1))}
                      aria-label="Move down"
                    >
                      <ChevronDown size={12} />
                    </button>
                  </div>

                  <GripVertical size={13} className="text-content-muted shrink-0" />

                  {/* Label */}
                  <input
                    value={field.label}
                    onChange={(e) => updateField(realIdx, { label: e.target.value })}
                    className={INPUT}
                    placeholder="Field label"
                  />

                  {/* Key badge */}
                  <span className="hidden md:block text-xs text-content-muted font-mono w-48 shrink-0 truncate">
                    {field.key}
                  </span>

                  {/* Visibility */}
                  <VisibilityToggle
                    value={field.visibility}
                    onChange={(v) => updateField(realIdx, { visibility: v })}
                  />

                  {/* Hide button */}
                  <button
                    type="button"
                    className={`${ICON_BTN} hover:text-red-500 hover:bg-red-50`}
                    onClick={() => removeField(realIdx)}
                    aria-label="Hide field"
                    title="Hide this field"
                  >
                    <EyeOff size={14} />
                  </button>
                </div>
              )
            })}
          </div>

          {/* Restore hidden field */}
          {availableToAdd.length > 0 && (
            <div className="mt-3 flex items-center gap-2">
              <select
                value={newFieldKey}
                onChange={(e) => setNewFieldKey(e.target.value)}
                className="text-xs border border-border-default rounded px-2 py-1.5 text-content-secondary focus:outline-none focus:border-accent"
              >
                <option value="">Restore a hidden field…</option>
                {availableToAdd.map((d) => (
                  <option key={d.key} value={d.key}>
                    {fields.find((f) => f.key === d.key)?.label || d.defaultLabel}
                  </option>
                ))}
              </select>
              {newFieldKey && (
                <button
                  type="button"
                  onClick={() => restoreField(newFieldKey)}
                  className="text-xs px-2 py-1.5 rounded bg-accent text-white hover:bg-accent-hover transition-colors"
                >
                  Restore
                </button>
              )}
            </div>
          )}
        </section>

        {/* ---------------------------------------------------------------- */}
        {/* Component Schema                                                  */}
        {/* ---------------------------------------------------------------- */}
        <section>
          <div className="mb-3">
            <h3 className="text-sm font-semibold text-content-secondary uppercase tracking-wide">
              Component Schema
            </h3>
            <p className="text-xs text-content-muted mt-0.5">
              Define the expected component types that appear as column pairs in the Excel file (cols 11+).
            </p>
          </div>

          <div className="space-y-1.5">
            {pairs.length === 0 && (
              <p className="text-sm text-content-muted italic px-3">No component types defined.</p>
            )}
            {pairs.map((pair, i) => (
              <div key={i} className={ROW}>
                {/* Reorder */}
                <div className="flex flex-col gap-0.5 shrink-0">
                  <button
                    type="button"
                    className={ICON_BTN}
                    disabled={i === 0}
                    onClick={() => setPairs((p) => moveItem(p, i, i - 1))}
                    aria-label="Move up"
                  >
                    <ChevronUp size={12} />
                  </button>
                  <button
                    type="button"
                    className={ICON_BTN}
                    disabled={i === pairs.length - 1}
                    onClick={() => setPairs((p) => moveItem(p, i, i + 1))}
                    aria-label="Move down"
                  >
                    <ChevronDown size={12} />
                  </button>
                </div>

                <GripVertical size={13} className="text-content-muted shrink-0" />

                {/* Index badge */}
                <span className="text-xs text-content-muted font-mono w-6 text-center shrink-0">
                  {i + 1}
                </span>

                {/* Component type name */}
                <input
                  value={pair.component_type}
                  onChange={(e) => updatePair(i, { component_type: e.target.value })}
                  placeholder="Component type name"
                  className={INPUT}
                />

                {/* Required toggle */}
                <button
                  type="button"
                  onClick={() => updatePair(i, { required: !pair.required })}
                  className={`px-2.5 py-1 rounded text-xs font-medium shrink-0 transition-colors ${
                    pair.required
                      ? 'text-white'
                      : 'bg-surface-muted text-content-secondary hover:bg-surface-hover'
                  }`}
                  style={pair.required ? { backgroundColor: 'var(--color-accent)' } : undefined}
                  title="Toggle required"
                >
                  {pair.required ? 'Required' : 'Optional'}
                </button>

                {/* Delete */}
                <button
                  type="button"
                  className={`${ICON_BTN} hover:text-red-500 hover:bg-red-50`}
                  onClick={() => removePair(i)}
                  aria-label="Delete component"
                >
                  <Trash2 size={14} />
                </button>
              </div>
            ))}
          </div>

          <button
            type="button"
            onClick={addPair}
            className="mt-3 inline-flex items-center gap-1.5 text-xs font-medium text-accent hover:text-accent-hover px-3 py-1.5 rounded border border-border-default hover:bg-accent-light transition-colors"
          >
            <Plus size={13} />
            Add component type
          </button>
        </section>
      </div>
    </div>
  )
}
