import React, { useState, useRef } from 'react';
import type { EditorStore } from '../../store/editorStore';
import { DEFAULT_GLOBAL_STYLES } from '../../store/editorStore';
import type { TokenCategory, DesignToken } from '../../types';
import { DEFAULT_DESIGN_SYSTEM, TOKEN_CATEGORY_LABELS, cssVarName } from '../../utils/designTokens';

// ── Types ────────────────────────────────────────────────────────────────────

type GSTab = 'colors' | 'typography' | 'effects' | 'layout' | 'buttons';
type TypoSub = 'families' | 'sizes' | 'lineHeights' | 'letterSpacing' | 'presets';
type EffectsSub = 'radius' | 'shadows' | 'opacity';
type LayoutSub = 'spacing' | 'containers';

interface Props {
  store: EditorStore;
  onSave: () => void;
}

// ── Helpers ──────────────────────────────────────────────────────────────────

const FONT_WEIGHTS = ['100','200','300','400','500','600','700','800','900'];
const TEXT_TRANSFORMS = ['none','uppercase','lowercase','capitalize'];
/** Build font family options from the PHP-injected config, falling back to a
 *  small hardcoded list if config is unavailable. */
function getFontFamilies(): string[] {
  const config = (window as any).jalpiEditorConfig;
  if (config?.fonts?.length) {
    return [
      'inherit',
      ...config.fonts
        .filter((f: { value: string }) => f.value)
        .map((f: { value: string }) => f.value),
    ];
  }
  return [
    'inherit',
    'Inter, sans-serif',
    'Roboto, sans-serif',
    'Open Sans, sans-serif',
    'system-ui, sans-serif',
  ];
}
const FONT_FAMILIES = getFontFamilies();

// ── Generic atomic token list editor ────────────────────────────────────────
// One implementation shared by all 8 atomic Design System categories (colors,
// fontFamilies, fontSizes, lineHeights, letterSpacing, borderRadius,
// boxShadows, spacing, containerWidths) instead of 8 near-duplicate tabs.
// Responsive editing reuses the SAME global store.state.breakpoint the canvas
// and TopBar breakpoint switcher already drive — switching device up top
// changes which value (value/tabletValue/mobileValue) this editor targets.

function TokenListEditor({
  store,
  category,
  kind = 'text',
  valueOptions,
  placeholder = '',
}: {
  store: EditorStore;
  category: TokenCategory;
  kind?: 'color' | 'text';
  valueOptions?: string[];
  placeholder?: string;
}) {
  const tokens = store.state.designSystem[category] as DesignToken[];
  const [editing, setEditing] = useState<string | null>(null);
  const bp = store.state.breakpoint;
  const field: 'value' | 'tabletValue' | 'mobileValue' =
    bp === 'tablet' ? 'tabletValue' : bp === 'mobile' ? 'mobileValue' : 'value';

  return (
    <div className="jalpi-gs-tab">
      <p className="jalpi-gs-tab__hint">
        {kind === 'color'
          ? <>Global colors appear as palette swatches in every color picker and are injected as CSS variables (e.g. <code>{cssVarName(category, 'primary')}</code>).</>
          : <>Link any matching control via its globe icon in the inspector. Injected as CSS variables (e.g. <code>{cssVarName(category, tokens[0]?.id ?? 'id')}</code>).</>}
        {bp !== 'desktop' && (
          <> Editing <strong>{bp === 'tablet' ? 'Tablet' : 'Mobile'}</strong> overrides — leave blank to inherit the Desktop value.</>
        )}
      </p>

      <div className="jalpi-gs-colors">
        {tokens.map((token) => {
          const rawValue = token[field] ?? '';
          const swatchColor = (rawValue || token.value || '#000000');
          return (
            <div key={token.id} className={`jalpi-gs-color${editing === token.id ? ' is-editing' : ''}`}>
              <div className="jalpi-gs-color__header">
                {kind === 'color' && (
                  <label className="jalpi-gs-color__swatch-wrap" title="Click to change color">
                    <span className="jalpi-gs-color__swatch" style={{ background: swatchColor }} />
                    <input
                      type="color"
                      className="jalpi-gs-color__native"
                      value={/^#[0-9a-fA-F]{6}$/.test(swatchColor) ? swatchColor : '#000000'}
                      onChange={(e) => store.dsUpdateToken(category, token.id, { [field]: e.target.value })}
                    />
                  </label>
                )}
                <span className="jalpi-gs-color__name" onClick={() => setEditing(editing === token.id ? null : token.id)}>
                  {token.name}
                </span>
                <span className="jalpi-gs-color__hex">{rawValue || (field !== 'value' ? 'inherit' : '—')}</span>
                <button className="jalpi-gs-color__edit" onClick={() => setEditing(editing === token.id ? null : token.id)} title="Edit">
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
                    <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
                  </svg>
                </button>
                <button
                  className="jalpi-gs-color__del"
                  onClick={() => { if (editing === token.id) setEditing(null); store.dsRemoveToken(category, token.id); }}
                  title="Delete"
                >
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                    <path d="M18 6L6 18M6 6l12 12"/>
                  </svg>
                </button>
              </div>

              {editing === token.id && (
                <div className="jalpi-gs-color__editor">
                  <div className="jalpi-gs-field">
                    <label className="jalpi-gs-field__label">Name</label>
                    <input
                      className="jalpi-gs-field__input"
                      value={token.name}
                      onChange={(e) => store.dsUpdateToken(category, token.id, { name: e.target.value })}
                      placeholder="Token name"
                    />
                  </div>
                  <div className="jalpi-gs-field">
                    <label className="jalpi-gs-field__label">
                      Value{bp !== 'desktop' ? ` (${bp})` : ''}
                    </label>
                    {valueOptions ? (
                      <select
                        className="jalpi-gs-field__select"
                        value={rawValue || (field !== 'value' ? '' : token.value)}
                        onChange={(e) => store.dsUpdateToken(category, token.id, { [field]: e.target.value })}
                      >
                        {field !== 'value' && <option value="">— Inherit —</option>}
                        {valueOptions.map((f) => <option key={f} value={f}>{f.split(',')[0]}</option>)}
                      </select>
                    ) : (
                      <input
                        className="jalpi-gs-field__input jalpi-gs-field__input--mono"
                        value={rawValue}
                        onChange={(e) => store.dsUpdateToken(category, token.id, { [field]: e.target.value })}
                        placeholder={field !== 'value' ? (token.value || placeholder) : placeholder}
                      />
                    )}
                  </div>
                  <p className="jalpi-gs-color__var-hint">
                    CSS var: <code>{cssVarName(category, token.id)}</code>
                  </p>
                </div>
              )}
            </div>
          );
        })}
      </div>

      <button className="jalpi-gs-add-btn" onClick={() => store.dsAddToken(category)}>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
          <path d="M12 5v14M5 12h14"/>
        </svg>
        Add {TOKEN_CATEGORY_LABELS[category]}
      </button>
    </div>
  );
}

// ── Typography presets tab (composite, unchanged shape — now site-wide) ────

function TypographyPresetsTab({ store }: Props) {
  const gs = store.state.designSystem;
  const [expanded, setExpanded] = useState<string | null>(null);
  const toggle = (id: string) => setExpanded((prev) => (prev === id ? null : id));

  return (
    <div className="jalpi-gs-tab">
      <p className="jalpi-gs-tab__hint">
        Link heading and text elements to a preset via the inspector. Updates auto-propagate to all linked elements.
      </p>

      <div className="jalpi-gs-list">
        {gs.typography.map((preset) => (
          <div key={preset.id} className={`jalpi-gs-preset${expanded === preset.id ? ' is-open' : ''}`}>
            <div className="jalpi-gs-preset__header" onClick={() => toggle(preset.id)}>
              <div
                className="jalpi-gs-preset__preview"
                style={{
                  fontFamily:    preset.fontFamily ?? 'inherit',
                  fontSize:      preset.fontSize   ?? '16px',
                  fontWeight:    preset.fontWeight ?? '400',
                  lineHeight:    preset.lineHeight ?? '1.4',
                  letterSpacing: preset.letterSpacing ?? '0',
                  textTransform: (preset.textTransform ?? 'none') as React.CSSProperties['textTransform'],
                  color:         preset.color ?? '#111827',
                }}
              >
                {preset.name}
              </div>
              <div className="jalpi-gs-preset__meta">
                <span>{preset.fontSize ?? '—'}</span>
                <span>{preset.fontWeight ? `w${preset.fontWeight}` : ''}</span>
              </div>
              <button
                className="jalpi-gs-preset__del"
                onClick={(e) => { e.stopPropagation(); store.dsRemoveTypography(preset.id); }}
                title="Delete preset"
              >
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
                  <path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6"/>
                </svg>
              </button>
              <svg className="jalpi-gs-preset__chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                <path d="M6 9l6 6 6-6"/>
              </svg>
            </div>

            {expanded === preset.id && (
              <div className="jalpi-gs-preset__body">
                <div className="jalpi-gs-row2">
                  <GSField label="Name">
                    <input className="jalpi-gs-field__input" value={preset.name}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { name: e.target.value })} />
                  </GSField>
                  <GSField label="Font Family">
                    <select className="jalpi-gs-field__select"
                      value={preset.fontFamily ?? 'inherit'}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { fontFamily: e.target.value })}>
                      {FONT_FAMILIES.map((f) => <option key={f} value={f}>{f.split(',')[0]}</option>)}
                    </select>
                  </GSField>
                </div>
                <div className="jalpi-gs-row3">
                  <GSField label="Size">
                    <input className="jalpi-gs-field__input" value={preset.fontSize ?? ''}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { fontSize: e.target.value })}
                      placeholder="16px" />
                  </GSField>
                  <GSField label="Weight">
                    <select className="jalpi-gs-field__select"
                      value={preset.fontWeight ?? '400'}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { fontWeight: e.target.value })}>
                      {FONT_WEIGHTS.map((w) => <option key={w} value={w}>{w}</option>)}
                    </select>
                  </GSField>
                  <GSField label="Line Height">
                    <input className="jalpi-gs-field__input" value={preset.lineHeight ?? ''}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { lineHeight: e.target.value })}
                      placeholder="1.5" />
                  </GSField>
                </div>
                <div className="jalpi-gs-row3">
                  <GSField label="Letter Spacing">
                    <input className="jalpi-gs-field__input" value={preset.letterSpacing ?? ''}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { letterSpacing: e.target.value })}
                      placeholder="0em" />
                  </GSField>
                  <GSField label="Transform">
                    <select className="jalpi-gs-field__select"
                      value={preset.textTransform ?? 'none'}
                      onChange={(e) => store.dsUpdateTypography(preset.id, { textTransform: e.target.value })}>
                      {TEXT_TRANSFORMS.map((t) => <option key={t} value={t}>{t}</option>)}
                    </select>
                  </GSField>
                  <GSField label="Color">
                    <div className="jalpi-gs-colorpick">
                      <label className="jalpi-gs-colorpick__swatch-wrap">
                        <span className="jalpi-gs-colorpick__swatch" style={{ background: preset.color ?? '#111827' }} />
                        <input type="color" className="jalpi-gs-color__native"
                          value={preset.color ?? '#111827'}
                          onChange={(e) => store.dsUpdateTypography(preset.id, { color: e.target.value })} />
                      </label>
                      <input className="jalpi-gs-field__input jalpi-gs-field__input--mono"
                        value={preset.color ?? ''}
                        onChange={(e) => store.dsUpdateTypography(preset.id, { color: e.target.value })}
                        placeholder="#111827" />
                    </div>
                  </GSField>
                </div>
              </div>
            )}
          </div>
        ))}
      </div>

      <button className="jalpi-gs-add-btn" onClick={() => store.dsAddTypography()}>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
          <path d="M12 5v14M5 12h14"/>
        </svg>
        Add Typography Preset
      </button>
    </div>
  );
}

// ── Buttons tab (composite, unchanged shape — now site-wide) ───────────────

function ButtonsTab({ store }: Props) {
  const gs = store.state.designSystem;
  const [expanded, setExpanded] = useState<string | null>(null);
  const toggle = (id: string) => setExpanded((prev) => (prev === id ? null : id));

  return (
    <div className="jalpi-gs-tab">
      <p className="jalpi-gs-tab__hint">
        Link button elements to a preset via the inspector. Style changes apply across all linked elements instantly.
      </p>

      <div className="jalpi-gs-list">
        {gs.buttons.map((preset) => (
          <div key={preset.id} className={`jalpi-gs-preset${expanded === preset.id ? ' is-open' : ''}`}>
            <div className="jalpi-gs-preset__header" onClick={() => toggle(preset.id)}>
              <span
                className="jalpi-gs-btn-preview"
                style={{
                  backgroundColor: preset.backgroundColor ?? '#1a1a1a',
                  color:           preset.color ?? '#fff',
                  borderRadius:    preset.borderRadius ?? '8px',
                  paddingTop:      preset.paddingTop    ?? '8px',
                  paddingBottom:   preset.paddingBottom ?? '8px',
                  paddingLeft:     preset.paddingLeft   ?? '16px',
                  paddingRight:    preset.paddingRight  ?? '16px',
                  fontSize:        preset.fontSize      ?? '14px',
                  fontWeight:      preset.fontWeight    ?? '600',
                  border:          preset.border !== 'none' ? (preset.border ?? 'none') : 'none',
                  boxShadow:       preset.boxShadow    ?? 'none',
                  fontFamily:      preset.fontFamily   ?? 'inherit',
                  textTransform:   (preset.textTransform ?? 'none') as React.CSSProperties['textTransform'],
                  display:         'inline-block',
                  lineHeight:      '1',
                  whiteSpace:      'nowrap',
                }}
              >
                {preset.name}
              </span>

              <button
                className="jalpi-gs-preset__del"
                onClick={(e) => { e.stopPropagation(); store.dsRemoveButton(preset.id); }}
                title="Delete preset"
              >
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
                  <path d="M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6"/>
                </svg>
              </button>
              <svg className="jalpi-gs-preset__chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                <path d="M6 9l6 6 6-6"/>
              </svg>
            </div>

            {expanded === preset.id && (
              <div className="jalpi-gs-preset__body">
                <div className="jalpi-gs-row2">
                  <GSField label="Name">
                    <input className="jalpi-gs-field__input" value={preset.name}
                      onChange={(e) => store.dsUpdateButton(preset.id, { name: e.target.value })} />
                  </GSField>
                  <GSField label="Font Family">
                    <select className="jalpi-gs-field__select"
                      value={preset.fontFamily ?? 'inherit'}
                      onChange={(e) => store.dsUpdateButton(preset.id, { fontFamily: e.target.value })}>
                      {FONT_FAMILIES.map((f) => <option key={f} value={f}>{f.split(',')[0]}</option>)}
                    </select>
                  </GSField>
                </div>
                <div className="jalpi-gs-row2">
                  <GSField label="Background">
                    <div className="jalpi-gs-colorpick">
                      <label className="jalpi-gs-colorpick__swatch-wrap">
                        <span className="jalpi-gs-colorpick__swatch" style={{ background: preset.backgroundColor ?? '#1a1a1a' }} />
                        <input type="color" className="jalpi-gs-color__native"
                          value={/^#[0-9a-fA-F]{6}$/.test(preset.backgroundColor ?? '') ? preset.backgroundColor! : '#1a1a1a'}
                          onChange={(e) => store.dsUpdateButton(preset.id, { backgroundColor: e.target.value })} />
                      </label>
                      <input className="jalpi-gs-field__input jalpi-gs-field__input--mono"
                        value={preset.backgroundColor ?? ''}
                        onChange={(e) => store.dsUpdateButton(preset.id, { backgroundColor: e.target.value })}
                        placeholder="#1a1a1a or transparent" />
                    </div>
                  </GSField>
                  <GSField label="Text Color">
                    <div className="jalpi-gs-colorpick">
                      <label className="jalpi-gs-colorpick__swatch-wrap">
                        <span className="jalpi-gs-colorpick__swatch" style={{ background: preset.color ?? '#fff' }} />
                        <input type="color" className="jalpi-gs-color__native"
                          value={/^#[0-9a-fA-F]{6}$/.test(preset.color ?? '') ? preset.color! : '#ffffff'}
                          onChange={(e) => store.dsUpdateButton(preset.id, { color: e.target.value })} />
                      </label>
                      <input className="jalpi-gs-field__input jalpi-gs-field__input--mono"
                        value={preset.color ?? ''}
                        onChange={(e) => store.dsUpdateButton(preset.id, { color: e.target.value })}
                        placeholder="#ffffff" />
                    </div>
                  </GSField>
                </div>
                <div className="jalpi-gs-row3">
                  <GSField label="Font Size">
                    <input className="jalpi-gs-field__input" value={preset.fontSize ?? ''}
                      onChange={(e) => store.dsUpdateButton(preset.id, { fontSize: e.target.value })}
                      placeholder="15px" />
                  </GSField>
                  <GSField label="Font Weight">
                    <select className="jalpi-gs-field__select"
                      value={preset.fontWeight ?? '600'}
                      onChange={(e) => store.dsUpdateButton(preset.id, { fontWeight: e.target.value })}>
                      {FONT_WEIGHTS.map((w) => <option key={w} value={w}>{w}</option>)}
                    </select>
                  </GSField>
                  <GSField label="Border Radius">
                    <input className="jalpi-gs-field__input" value={preset.borderRadius ?? ''}
                      onChange={(e) => store.dsUpdateButton(preset.id, { borderRadius: e.target.value })}
                      placeholder="8px" />
                  </GSField>
                </div>
                <div className="jalpi-gs-row2">
                  <GSField label="Padding H (L/R)">
                    <input className="jalpi-gs-field__input" value={preset.paddingLeft ?? ''}
                      onChange={(e) => store.dsUpdateButton(preset.id, { paddingLeft: e.target.value, paddingRight: e.target.value })}
                      placeholder="24px" />
                  </GSField>
                  <GSField label="Padding V (T/B)">
                    <input className="jalpi-gs-field__input" value={preset.paddingTop ?? ''}
                      onChange={(e) => store.dsUpdateButton(preset.id, { paddingTop: e.target.value, paddingBottom: e.target.value })}
                      placeholder="12px" />
                  </GSField>
                </div>
                <div className="jalpi-gs-row2">
                  <GSField label="Border">
                    <input className="jalpi-gs-field__input" value={preset.border ?? ''}
                      onChange={(e) => store.dsUpdateButton(preset.id, { border: e.target.value })}
                      placeholder="none or 1.5px solid #1a1a1a" />
                  </GSField>
                  <GSField label="Box Shadow">
                    <input className="jalpi-gs-field__input" value={preset.boxShadow ?? ''}
                      onChange={(e) => store.dsUpdateButton(preset.id, { boxShadow: e.target.value })}
                      placeholder="none" />
                  </GSField>
                </div>
              </div>
            )}
          </div>
        ))}
      </div>

      <button className="jalpi-gs-add-btn" onClick={() => store.dsAddButton()}>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
          <path d="M12 5v14M5 12h14"/>
        </svg>
        Add Button Preset
      </button>
    </div>
  );
}

// ── Shared field wrapper ─────────────────────────────────────────────────────

function GSField({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="jalpi-gs-field">
      <label className="jalpi-gs-field__label">{label}</label>
      {children}
    </div>
  );
}

// ── Sub-nav (pills) for grouped tabs ─────────────────────────────────────────

function SubNav<T extends string>({ tabs, active, onChange }: { tabs: Array<{ id: T; label: string }>; active: T; onChange: (id: T) => void }) {
  return (
    <div className="jalpi-gs__subnav">
      {tabs.map((t) => (
        <button
          key={t.id}
          className={`jalpi-gs__subnav-btn${active === t.id ? ' is-active' : ''}`}
          onClick={() => onChange(t.id)}
        >
          {t.label}
        </button>
      ))}
    </div>
  );
}

// ── Export / Import ──────────────────────────────────────────────────────────
// Export is client-only (serializes the already-loaded store.state.designSystem).
// Import reads a JSON file, then asks Merge-vs-Replace before touching store
// state — the actual persisted save still goes through the normal
// POST /design-system flow, so Jalpi_Sanitizer::sanitize_design_system() on the
// server remains the authority on anything a user imports (see editorStore.ts's
// dsImportJSON, which does light client-side normalization only).

function downloadJSON(data: unknown, filename: string): void {
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
}

function ExportImportControls({ store }: Props) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [pending, setPending] = useState<Record<string, unknown> | null>(null);
  const [error, setError] = useState<string | null>(null);

  const handleExport = () => {
    const date = new Date().toISOString().slice(0, 10);
    downloadJSON(store.state.designSystem, `jalpi-design-system-${date}.json`);
  };

  const handleFileSelected = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    e.target.value = ''; // allow re-selecting the same file later
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      try {
        const parsed = JSON.parse(String(reader.result));
        if (!parsed || typeof parsed !== 'object') throw new Error('not an object');
        setError(null);
        setPending(parsed);
      } catch {
        setError('That file isn\'t valid Design System JSON.');
      }
    };
    reader.readAsText(file);
  };

  const applyImport = (mode: 'merge' | 'replace') => {
    if (!pending) return;
    store.dsImportJSON(pending, mode);
    setPending(null);
  };

  return (
    <div className="jalpi-gs__io-actions">
      <button type="button" className="jalpi-gs__io-btn" onClick={handleExport} title="Download the current Design System as JSON">
        Export
      </button>
      <button type="button" className="jalpi-gs__io-btn" onClick={() => fileInputRef.current?.click()} title="Import a Design System JSON file">
        Import
      </button>
      <input ref={fileInputRef} type="file" accept="application/json,.json" style={{ display: 'none' }} onChange={handleFileSelected} />

      {error && (
        <div className="jalpi-gs__import-banner jalpi-gs__io-popover">
          <span>{error}</span>
          <div className="jalpi-gs__import-banner-actions">
            <button className="jalpi-gs__import-banner-dismiss" onClick={() => setError(null)}>Dismiss</button>
          </div>
        </div>
      )}

      {pending && (
        <div className="jalpi-gs__import-banner jalpi-gs__io-popover">
          <span>Import this file — merge with existing tokens, or replace them entirely?</span>
          <div className="jalpi-gs__import-banner-actions">
            <button className="jalpi-gs__import-banner-btn" onClick={() => applyImport('merge')}>Merge</button>
            <button className="jalpi-gs__import-banner-btn" onClick={() => applyImport('replace')}>Replace</button>
            <button className="jalpi-gs__import-banner-dismiss" onClick={() => setPending(null)}>Cancel</button>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Legacy per-page styles import banner ────────────────────────────────────

function ImportLegacyBanner({ store }: Props) {
  const [dismissed, setDismissed] = useState(false);
  const legacy = store.state.pageData.globalStyles;
  const looksUntouched = JSON.stringify(store.state.designSystem.colors) === JSON.stringify(DEFAULT_DESIGN_SYSTEM.colors)
    && JSON.stringify(store.state.designSystem.typography) === JSON.stringify(DEFAULT_DESIGN_SYSTEM.typography)
    && JSON.stringify(store.state.designSystem.buttons) === JSON.stringify(DEFAULT_DESIGN_SYSTEM.buttons);
  const legacyDiffers = legacy && JSON.stringify(legacy) !== JSON.stringify(DEFAULT_GLOBAL_STYLES);

  if (dismissed || !legacy || !legacyDiffers || !looksUntouched) return null;

  return (
    <div className="jalpi-gs__import-banner">
      <span>This page has custom legacy Global Styles. Import them into the new site-wide Design System?</span>
      <div className="jalpi-gs__import-banner-actions">
        <button className="jalpi-gs__import-banner-btn" onClick={() => { store.dsImportFromLegacy(legacy); setDismissed(true); }}>
          Import
        </button>
        <button className="jalpi-gs__import-banner-dismiss" onClick={() => setDismissed(true)}>
          Dismiss
        </button>
      </div>
    </div>
  );
}

// ── Main panel ───────────────────────────────────────────────────────────────

export function GlobalStylesPanel({ store, onSave }: Props) {
  const [tab, setTab] = useState<GSTab>('colors');
  const [typoSub, setTypoSub] = useState<TypoSub>('presets');
  const [effectsSub, setEffectsSub] = useState<EffectsSub>('radius');
  const [layoutSub, setLayoutSub] = useState<LayoutSub>('spacing');

  const TABS: Array<{ id: GSTab; label: string }> = [
    { id: 'colors',     label: 'Colors' },
    { id: 'typography', label: 'Typography' },
    { id: 'effects',    label: 'Effects' },
    { id: 'layout',     label: 'Layout' },
    { id: 'buttons',    label: 'Buttons' },
  ];

  const { designSystemDirty, designSystemSaving } = store.state;
  const canManage = (window as any).jalpiEditorConfig?.canManageDesignSystem !== false;

  return (
    <div className="jalpi-gs">
      <div className="jalpi-gs__header">
        <div className="jalpi-gs__nav">
          {TABS.map((t) => (
            <button
              key={t.id}
              className={`jalpi-gs__nav-btn${tab === t.id ? ' is-active' : ''}`}
              onClick={() => setTab(t.id)}
            >
              {t.label}
            </button>
          ))}
        </div>
        <div className="jalpi-gs__save-status">
          <ExportImportControls store={store} onSave={onSave} />
          <div className="jalpi-gs__save-status-right">
            {!canManage ? (
              <span className="jalpi-gs__save-status-text">View only</span>
            ) : designSystemSaving ? (
              <span className="jalpi-gs__save-status-text">Saving…</span>
            ) : designSystemDirty ? (
              <button className="jalpi-gs__save-btn" onClick={onSave}>Save Design System</button>
            ) : (
              <span className="jalpi-gs__save-status-text">Saved</span>
            )}
          </div>
        </div>
      </div>

      <fieldset className="jalpi-gs__body-fieldset" disabled={!canManage}>
        <div className="jalpi-gs__body">
          <ImportLegacyBanner store={store} onSave={onSave} />

          {tab === 'colors' && (
            <TokenListEditor store={store} category="colors" kind="color" placeholder="#1a1a1a" />
          )}

          {tab === 'typography' && (
            <>
              <SubNav
                tabs={[
                  { id: 'families' as TypoSub, label: 'Families' },
                  { id: 'sizes' as TypoSub, label: 'Sizes' },
                  { id: 'lineHeights' as TypoSub, label: 'Line Heights' },
                  { id: 'letterSpacing' as TypoSub, label: 'Letter Spacing' },
                  { id: 'presets' as TypoSub, label: 'Presets' },
                ]}
                active={typoSub}
                onChange={setTypoSub}
              />
              {typoSub === 'families' && <TokenListEditor store={store} category="fontFamilies" kind="text" valueOptions={FONT_FAMILIES} />}
              {typoSub === 'sizes' && <TokenListEditor store={store} category="fontSizes" kind="text" placeholder="16px" />}
              {typoSub === 'lineHeights' && <TokenListEditor store={store} category="lineHeights" kind="text" placeholder="1.5" />}
              {typoSub === 'letterSpacing' && <TokenListEditor store={store} category="letterSpacing" kind="text" placeholder="0.02em" />}
              {typoSub === 'presets' && <TypographyPresetsTab store={store} onSave={onSave} />}
            </>
          )}

          {tab === 'effects' && (
            <>
              <SubNav
                tabs={[
                  { id: 'radius' as EffectsSub, label: 'Border Radius' },
                  { id: 'shadows' as EffectsSub, label: 'Box Shadows' },
                  { id: 'opacity' as EffectsSub, label: 'Opacity' },
                ]}
                active={effectsSub}
                onChange={setEffectsSub}
              />
              {effectsSub === 'radius' && <TokenListEditor store={store} category="borderRadius" kind="text" placeholder="8px" />}
              {effectsSub === 'shadows' && <TokenListEditor store={store} category="boxShadows" kind="text" placeholder="0 2px 12px rgba(0,0,0,0.15)" />}
              {effectsSub === 'opacity' && <TokenListEditor store={store} category="opacity" kind="text" placeholder="1" />}
            </>
          )}

          {tab === 'layout' && (
            <>
              <SubNav
                tabs={[
                  { id: 'spacing' as LayoutSub, label: 'Spacing' },
                  { id: 'containers' as LayoutSub, label: 'Container Widths' },
                ]}
                active={layoutSub}
                onChange={setLayoutSub}
              />
              {layoutSub === 'spacing' && <TokenListEditor store={store} category="spacing" kind="text" placeholder="16px" />}
              {layoutSub === 'containers' && <TokenListEditor store={store} category="containerWidths" kind="text" placeholder="1200px" />}
            </>
          )}

          {tab === 'buttons' && <ButtonsTab store={store} onSave={onSave} />}
        </div>
      </fieldset>
    </div>
  );
}
