'use client'

import { useEffect, useState } from 'react'
import { Eye, EyeOff, Plus, X } from 'lucide-react'
import { MediaPickerModal } from '../../components/MediaPickerModal.js'
import type { PageSection } from '../../lib/page-editor-service.js'
import type { SectionSettings } from './section-types.js'
import { getSectionType, type SectionFieldDef } from './section-types.js'

interface SectionInspectorProps {
  section: PageSection
  canEdit: boolean
  onClose: () => void
  onContentChange: (patch: Record<string, unknown>) => void
  onSettingsChange: (patch: Partial<SectionSettings>) => void
  onMetaChange: (patch: { name?: string; internalLabel?: string }) => void
  onToggleVisibility: () => void
}

const LABEL = 'text-foreground mb-1 block text-xs font-medium'
const INPUT =
  'border-input bg-input-background text-foreground focus-visible:ring-ring w-full rounded-md border px-2.5 py-1.5 text-sm focus-visible:ring-2 focus-visible:outline-none'

export function SectionInspector({
  section,
  canEdit,
  onClose,
  onContentChange,
  onSettingsChange,
  onMetaChange,
  onToggleVisibility,
}: SectionInspectorProps) {
  const def = getSectionType(section.sectionType)

  // Escape closes the inspector.
  useEffect(() => {
    function onKey(e: KeyboardEvent) {
      if (e.key === 'Escape') onClose()
    }
    document.addEventListener('keydown', onKey)
    return () => document.removeEventListener('keydown', onKey)
  }, [onClose])

  return (
    <aside
      role="dialog"
      aria-label={`Edit ${section.name}`}
      className="bg-card border-border flex h-full w-80 shrink-0 flex-col border-l"
    >
      <div className="border-border flex items-center justify-between border-b px-4 py-3">
        <div className="min-w-0">
          <h2 className="text-foreground truncate text-sm font-medium">{section.name}</h2>
          <p className="text-muted-foreground text-xs">{def?.name ?? 'Section'}</p>
        </div>
        <button
          type="button"
          onClick={onClose}
          aria-label="Close inspector"
          className="text-muted-foreground hover:text-foreground hover:bg-accent rounded p-1"
        >
          <X className="h-4 w-4" aria-hidden />
        </button>
      </div>

      <div className="flex-1 space-y-6 overflow-y-auto p-4">
        {!canEdit && (
          <p className="border-border bg-muted text-muted-foreground rounded-md border p-2 text-xs">
            You have read-only access to this page.
          </p>
        )}

        {/* Content fields (schema-driven) */}
        <fieldset disabled={!canEdit} className="space-y-3">
          <legend className="text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase">
            Content
          </legend>
          {def?.fields.map((field) => (
            <ContentField
              key={field.key}
              field={field}
              value={section.content[field.key]}
              onChange={(v) => onContentChange({ [field.key]: v })}
            />
          ))}
        </fieldset>

        {/* Section meta + visibility */}
        <fieldset disabled={!canEdit} className="space-y-3">
          <legend className="text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase">
            Section settings
          </legend>
          <div>
            <label className={LABEL} htmlFor="insp-name">
              Section name
            </label>
            <input
              id="insp-name"
              className={INPUT}
              value={section.name}
              onChange={(e) => onMetaChange({ name: e.target.value })}
            />
          </div>
          <div>
            <label className={LABEL} htmlFor="insp-internal">
              Internal label
            </label>
            <input
              id="insp-internal"
              className={INPUT}
              placeholder="Team-only note (optional)"
              value={section.internalLabel ?? ''}
              onChange={(e) => onMetaChange({ internalLabel: e.target.value })}
            />
          </div>
          <button
            type="button"
            onClick={onToggleVisibility}
            disabled={!canEdit}
            aria-pressed={!section.visible}
            className="border-border text-foreground hover:bg-accent flex w-full items-center justify-between rounded-md border px-2.5 py-1.5 text-sm disabled:opacity-50"
          >
            <span className="flex items-center gap-2">
              {section.visible ? (
                <Eye className="h-4 w-4" aria-hidden />
              ) : (
                <EyeOff className="h-4 w-4" aria-hidden />
              )}
              {section.visible ? 'Visible on page' : 'Hidden from page'}
            </span>
            <span className="text-muted-foreground text-xs">
              {section.visible ? 'Hide' : 'Show'}
            </span>
          </button>
        </fieldset>

        {/* Appearance */}
        <fieldset disabled={!canEdit} className="space-y-3">
          <legend className="text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase">
            Appearance
          </legend>
          <div>
            <label className={LABEL} htmlFor="insp-bg">
              Background
            </label>
            <select
              id="insp-bg"
              className={INPUT}
              value={section.settings.backgroundType ?? 'none'}
              onChange={(e) =>
                onSettingsChange({
                  backgroundType: e.target.value as SectionSettings['backgroundType'],
                })
              }
            >
              <option value="none">White</option>
              <option value="solid">Solid color</option>
              <option value="gradient">Gradient</option>
            </select>
          </div>
          {section.settings.backgroundType && section.settings.backgroundType !== 'none' && (
            <div>
              <label className={LABEL} htmlFor="insp-bgcolor">
                Color
              </label>
              <select
                id="insp-bgcolor"
                className={INPUT}
                value={section.settings.backgroundColor ?? 'purple'}
                onChange={(e) => onSettingsChange({ backgroundColor: e.target.value })}
              >
                <option value="purple">Purple</option>
                <option value="muted">Light gray</option>
              </select>
            </div>
          )}
          <div>
            <label className={LABEL} htmlFor="insp-pad">
              Spacing
            </label>
            <select
              id="insp-pad"
              className={INPUT}
              value={section.settings.paddingY ?? 'lg'}
              onChange={(e) =>
                onSettingsChange({ paddingY: e.target.value as SectionSettings['paddingY'] })
              }
            >
              <option value="sm">Small</option>
              <option value="md">Medium</option>
              <option value="lg">Large</option>
              <option value="xl">Extra large</option>
            </select>
          </div>
        </fieldset>

        {/* Advanced */}
        <fieldset disabled={!canEdit} className="space-y-3">
          <legend className="text-muted-foreground mb-2 text-[10px] font-semibold tracking-wider uppercase">
            Advanced
          </legend>
          <div>
            <label className={LABEL} htmlFor="insp-anchor">
              Anchor ID
            </label>
            <input
              id="insp-anchor"
              className={INPUT}
              placeholder="e.g. features"
              value={section.settings.anchorId ?? ''}
              onChange={(e) => onSettingsChange({ anchorId: e.target.value })}
            />
          </div>
          <div>
            <label className={LABEL} htmlFor="insp-css">
              CSS class
            </label>
            <input
              id="insp-css"
              className={INPUT}
              placeholder="custom-class"
              value={section.settings.cssClass ?? ''}
              onChange={(e) => onSettingsChange({ cssClass: e.target.value })}
            />
          </div>
        </fieldset>
      </div>
    </aside>
  )
}

// ─── Field renderers ─────────────────────────────────────────────────

function ContentField({
  field,
  value,
  onChange,
}: {
  field: SectionFieldDef
  value: unknown
  onChange: (v: unknown) => void
}) {
  const id = `insp-field-${field.key}`
  const text = typeof value === 'string' ? value : ''

  if (field.type === 'stats') {
    return <StatsField label={field.label} value={value} onChange={onChange} />
  }

  if (field.type === 'gallery') {
    return <GalleryField label={field.label} value={value} onChange={onChange} />
  }

  if (field.type === 'boolean') {
    return <BooleanField id={id} field={field} value={value === true} onChange={onChange} />
  }

  if (field.type === 'relationship') {
    return <RelationshipField id={id} field={field} value={value} onChange={onChange} />
  }

  if (field.type === 'media') {
    return <MediaField id={id} field={field} value={text} onChange={onChange} />
  }

  if (field.type === 'select') {
    return (
      <div>
        <label className={LABEL} htmlFor={id}>
          {field.label}
        </label>
        <select id={id} className={INPUT} value={text} onChange={(e) => onChange(e.target.value)}>
          {field.options?.map((o) => (
            <option key={o.value} value={o.value}>
              {o.label}
            </option>
          ))}
        </select>
      </div>
    )
  }

  if (field.type === 'textarea' || field.type === 'richText') {
    return (
      <div>
        <label className={LABEL} htmlFor={id}>
          {field.label}
          {field.required && <span className="text-destructive ml-0.5">*</span>}
        </label>
        <textarea
          id={id}
          className={`${INPUT} resize-y ${field.type === 'richText' ? 'min-h-[140px]' : 'min-h-[72px]'}`}
          value={text}
          placeholder={field.placeholder}
          onChange={(e) => onChange(e.target.value)}
        />
        {field.help && <p className="text-muted-foreground mt-1 text-xs">{field.help}</p>}
      </div>
    )
  }

  return (
    <div>
      <label className={LABEL} htmlFor={id}>
        {field.label}
        {field.required && <span className="text-destructive ml-0.5">*</span>}
      </label>
      <input
        id={id}
        type={field.type === 'url' ? 'url' : 'text'}
        className={INPUT}
        value={text}
        placeholder={field.placeholder}
        onChange={(e) => onChange(e.target.value)}
      />
      {field.help && <p className="text-muted-foreground mt-1 text-xs">{field.help}</p>}
    </div>
  )
}

function MediaField({
  id,
  field,
  value,
  onChange,
}: {
  id: string
  field: SectionFieldDef
  value: string
  onChange: (v: unknown) => void
}) {
  const [open, setOpen] = useState(false)
  return (
    <div>
      <label className={LABEL} htmlFor={id}>
        {field.label}
      </label>
      <div className="flex gap-2">
        <input
          id={id}
          className={`${INPUT} flex-1`}
          placeholder="https://…"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        />
        <button
          type="button"
          onClick={() => setOpen(true)}
          className="bg-accent text-foreground border-border hover:bg-accent/80 rounded-md border px-3 py-1.5 text-xs font-medium"
        >
          Browse
        </button>
      </div>
      {value && (
        <div className="border-border bg-muted mt-2 overflow-hidden rounded-md border">
          <img src={value} alt="" className="h-28 w-full object-contain" />
        </div>
      )}
      <MediaPickerModal
        open={open}
        onClose={() => setOpen(false)}
        onSelect={(url) => {
          onChange(url)
          setOpen(false)
        }}
        accept="image/*"
      />
    </div>
  )
}

function BooleanField({
  id,
  field,
  value,
  onChange,
}: {
  id: string
  field: SectionFieldDef
  value: boolean
  onChange: (v: unknown) => void
}) {
  return (
    <div>
      <button
        type="button"
        id={id}
        role="switch"
        aria-checked={value}
        onClick={() => onChange(!value)}
        className="border-border text-foreground hover:bg-accent flex w-full items-center justify-between rounded-md border px-2.5 py-1.5 text-sm"
      >
        <span>{field.label}</span>
        <span
          aria-hidden
          className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors ${
            value ? 'bg-primary' : 'bg-muted'
          }`}
        >
          <span
            className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
              value ? 'translate-x-4' : 'translate-x-0.5'
            }`}
          />
        </span>
      </button>
      {field.help && <p className="text-muted-foreground mt-1 text-xs">{field.help}</p>}
    </div>
  )
}

function RelationshipField({
  id,
  field,
  value,
  onChange,
}: {
  id: string
  field: SectionFieldDef
  value: unknown
  onChange: (v: unknown) => void
}) {
  // Stored as an array of slugs; edited as a newline/comma-separated list
  // so authors can hand-pick referenced documents without a live picker.
  const slugs = Array.isArray(value) ? (value as string[]) : []
  const text = slugs.join('\n')
  return (
    <div>
      <label className={LABEL} htmlFor={id}>
        {field.label}
      </label>
      <textarea
        id={id}
        className={`${INPUT} min-h-[72px] resize-y`}
        placeholder="one-slug-per-line"
        value={text}
        onChange={(e) =>
          onChange(
            e.target.value
              .split(/[\n,]/)
              .map((s) => s.trim())
              .filter(Boolean),
          )
        }
      />
      {field.help && <p className="text-muted-foreground mt-1 text-xs">{field.help}</p>}
    </div>
  )
}

interface ImageRow {
  url?: string
  alt?: string
  caption?: string
}

function GalleryField({
  label,
  value,
  onChange,
}: {
  label: string
  value: unknown
  onChange: (v: unknown) => void
}) {
  const rows: ImageRow[] = Array.isArray(value) ? (value as ImageRow[]) : []

  function update(index: number, patch: Partial<ImageRow>) {
    onChange(rows.map((r, i) => (i === index ? { ...r, ...patch } : r)))
  }
  function remove(index: number) {
    onChange(rows.filter((_, i) => i !== index))
  }
  function add() {
    onChange([...rows, { url: '', alt: '', caption: '' }])
  }

  return (
    <div>
      <span className={LABEL}>{label}</span>
      <div className="space-y-3">
        {rows.map((row, i) => (
          <div key={i} className="border-border rounded-md border p-2">
            <div className="mb-2 flex items-center justify-between">
              <span className="text-muted-foreground text-xs">Image {i + 1}</span>
              <button
                type="button"
                onClick={() => remove(i)}
                aria-label={`Remove image ${i + 1}`}
                className="text-muted-foreground hover:text-destructive rounded p-0.5"
              >
                <X className="h-3.5 w-3.5" aria-hidden />
              </button>
            </div>
            <div className="space-y-2">
              <input
                className={INPUT}
                placeholder="Image URL (https://…)"
                value={row.url ?? ''}
                onChange={(e) => update(i, { url: e.target.value })}
                aria-label={`Image ${i + 1} URL`}
              />
              <input
                className={INPUT}
                placeholder="Alt text (for accessibility)"
                value={row.alt ?? ''}
                onChange={(e) => update(i, { alt: e.target.value })}
                aria-label={`Image ${i + 1} alt text`}
              />
            </div>
          </div>
        ))}
      </div>
      <button
        type="button"
        onClick={add}
        className="border-border text-foreground hover:bg-accent mt-2 flex w-full items-center justify-center gap-1.5 rounded-md border border-dashed px-2 py-1.5 text-xs font-medium"
      >
        <Plus className="h-3.5 w-3.5" aria-hidden />
        Add image
      </button>
    </div>
  )
}

interface StatRow {
  value?: string
  label?: string
  description?: string
}

function StatsField({
  label,
  value,
  onChange,
}: {
  label: string
  value: unknown
  onChange: (v: unknown) => void
}) {
  const rows: StatRow[] = Array.isArray(value) ? (value as StatRow[]) : []

  function update(index: number, patch: Partial<StatRow>) {
    const next = rows.map((r, i) => (i === index ? { ...r, ...patch } : r))
    onChange(next)
  }
  function remove(index: number) {
    onChange(rows.filter((_, i) => i !== index))
  }
  function add() {
    onChange([...rows, { value: '', label: '', description: '' }])
  }

  return (
    <div>
      <span className={LABEL}>{label}</span>
      <div className="space-y-3">
        {rows.map((row, i) => (
          <div key={i} className="border-border rounded-md border p-2">
            <div className="mb-2 flex items-center justify-between">
              <span className="text-muted-foreground text-xs">Stat {i + 1}</span>
              <button
                type="button"
                onClick={() => remove(i)}
                aria-label={`Remove stat ${i + 1}`}
                className="text-muted-foreground hover:text-destructive rounded p-0.5"
              >
                <X className="h-3.5 w-3.5" aria-hidden />
              </button>
            </div>
            <div className="space-y-2">
              <input
                className={INPUT}
                placeholder="Value (e.g. 99.99%)"
                value={row.value ?? ''}
                onChange={(e) => update(i, { value: e.target.value })}
                aria-label={`Stat ${i + 1} value`}
              />
              <input
                className={INPUT}
                placeholder="Label (e.g. Uptime)"
                value={row.label ?? ''}
                onChange={(e) => update(i, { label: e.target.value })}
                aria-label={`Stat ${i + 1} label`}
              />
            </div>
          </div>
        ))}
      </div>
      <button
        type="button"
        onClick={add}
        className="border-border text-foreground hover:bg-accent mt-2 flex w-full items-center justify-center gap-1.5 rounded-md border border-dashed px-2 py-1.5 text-xs font-medium"
      >
        <Plus className="h-3.5 w-3.5" aria-hidden />
        Add stat
      </button>
    </div>
  )
}
