// components/page-builder/PageBuilder.tsx
'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useDroppable } from '@dnd-kit/core';
import {
  PageComponent,
  ContainerComponentProps,
  ContainerColumn,
  migrateToColumns,
} from '@/lib/page-builder/types';
import { ComponentType } from '@/lib/page-builder/component-registry';
import { createComponent, validateComponentData } from '@/lib/page-builder/utils';
import { DndProvider } from './providers/DndProvider';
import ComponentPalette from './ComponentPalette';
import { ComponentWrapper } from './ComponentWrapper';
import { ModalEditPanel } from './ModalEditPanel';
import { pageBuilderConfigs } from '@/lib/page-builder/config';
import { DeleteConfirmationModal } from './DeleteConfirmationModal';

interface PageBuilderProps {
  pageId: string;
  contentType: 'products' | 'services' | 'projects' | 'pages';
  title?: string;
  subtitle?: string;
}

const CLIPBOARD_KEY = 'pb_clipboard';
const MAX_HISTORY = 50;

interface Toast { id: number; message: string; type?: 'warning' | 'success' | 'info'; }

function ToastList({ toasts }: { toasts: Toast[] }) {
  if (!toasts.length) return null;
  return (
    <div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-50 flex flex-col items-center gap-2 pointer-events-none">
      {toasts.map(t => (
        <div key={t.id} className={`flex items-center gap-2.5 px-4 py-3 text-white text-sm font-medium rounded-xl shadow-var-modal ${
          t.type === 'success' ? 'bg-var-success' : t.type === 'info' ? 'bg-var-primary' : 'bg-var-surface-raised'
        }`}>
          {t.type === 'success' ? (
            <svg className="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
            </svg>
          ) : t.type === 'info' ? (
            <svg className="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          ) : (
            <svg className="w-4 h-4 text-var-warning shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
            </svg>
          )}
          {t.message}
        </div>
      ))}
    </div>
  );
}

function PasteZone({ onPaste, disabled }: { onPaste: () => void; disabled: boolean }) {
  if (disabled) return null;
  return (
    <button
      type="button"
      onClick={onPaste}
      className="w-full flex items-center justify-center gap-2 py-2.5 border-2 border-dashed border-var-info rounded-xl text-var-info text-xs font-medium bg-var-info-bg/50 hover:bg-var-info-bg hover:border-var-info transition-all"
    >
      <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
      </svg>
      Paste from clipboard here
    </button>
  );
}

function isContainerComp(c: PageComponent): c is PageComponent & { props: ContainerComponentProps } {
  return c.type === 'Container';
}

function deepCloneComponent(component: PageComponent, allComponents: PageComponent[]): { cloned: PageComponent; newChildren: PageComponent[] } {
  const newId = `${component.type.toLowerCase()}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
  const newChildren: PageComponent[] = [];

  if (!isContainerComp(component)) {
    return { cloned: { ...component, id: newId }, newChildren: [] };
  }

  const cols = migrateToColumns(component.props);
  const clonedCols: ContainerColumn[] = cols.map((col, ci) => {
    const newColChildIds: string[] = [];
    col.childIds.forEach(childId => {
      const child = allComponents.find(c => c.id === childId);
      if (!child) return;
      const { cloned, newChildren: grand } = deepCloneComponent(child, allComponents);
      newChildren.push(cloned, ...grand);
      newColChildIds.push(cloned.id);
    });
    return { id: `col-clone-${ci}-${Date.now()}`, childIds: newColChildIds };
  });

  return {
    cloned: {
      ...component,
      id: newId,
      props: {
        ...component.props,
        columns: clonedCols,
        childComponentIds: clonedCols.flatMap(c => c.childIds),
      },
    },
    newChildren,
  };
}

export default function PageBuilder({
  pageId,
  contentType,
  title = 'Page Builder',
  subtitle = 'Drag components to build your page',
}: PageBuilderProps) {

  const [components, setComponentsRaw] = useState<PageComponent[]>([]);
  const [editingComponent, setEditingComponent] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle');
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  const [componentToDelete, setComponentToDelete] = useState<string | null>(null);
  const [toasts, setToasts] = useState<Toast[]>([]);
  const [clipboardEmpty, setClipboardEmpty] = useState(true);

  const historyRef = useRef<PageComponent[][]>([]);
  const historyIdx = useRef(-1);
  const skipHistoryRef = useRef(false);

  const setComponents = useCallback((updater: PageComponent[] | ((prev: PageComponent[]) => PageComponent[])) => {
    setComponentsRaw(prev => {
      const next = typeof updater === 'function' ? updater(prev) : updater;
      if (!skipHistoryRef.current) {
        historyRef.current = historyRef.current.slice(0, historyIdx.current + 1);
        historyRef.current.push(prev);
        if (historyRef.current.length > MAX_HISTORY) historyRef.current.shift();
        historyIdx.current = historyRef.current.length - 1;
      }
      return next;
    });
  }, []);

  const showToast = useCallback((message: string, type: Toast['type'] = 'warning') => {
    const id = Date.now();
    setToasts(prev => [...prev, { id, message, type }]);
    setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), 3000);
  }, []);

  const undo = useCallback(() => {
    if (historyIdx.current < 0) return;
    const prev = historyRef.current[historyIdx.current];
    historyIdx.current -= 1;
    skipHistoryRef.current = true;
    setComponentsRaw(prev);
    skipHistoryRef.current = false;
    setHasUnsavedChanges(true);
    showToast('Undo', 'info');
  }, [showToast]);

  const redo = useCallback(() => {
    const future = historyRef.current[historyIdx.current + 1];
    if (!future) return;
    historyIdx.current += 1;
    skipHistoryRef.current = true;
    setComponentsRaw(future);
    skipHistoryRef.current = false;
    setHasUnsavedChanges(true);
    showToast('Redo', 'info');
  }, [showToast]);

  const canUndo = historyIdx.current >= 0;
  const canRedo = historyIdx.current < historyRef.current.length - 1;

  const config = pageBuilderConfigs[contentType];
  const buildApiUrl = (ep: string, id: string) => ep.replace('[id]', id);
  const markUnsaved = useCallback(() => setHasUnsavedChanges(true), []);

  const loadComponents = useCallback(async () => {
    if (!config) { setIsLoading(false); return; }
    try {
      setIsLoading(true);
      const res = await fetch(buildApiUrl(config.apiEndpoints.getLayout, pageId));
      if (res.ok) {
        const data = await res.json();
        if (validateComponentData(data.components)) {
          skipHistoryRef.current = true;
          setComponentsRaw(data.components);
          skipHistoryRef.current = false;
          setHasUnsavedChanges(false);
          historyRef.current = [];
          historyIdx.current = -1;
        }
      }
    } catch (e) { console.error('Failed to load', e); }
    finally { setIsLoading(false); }
  }, [pageId, config]);

  useEffect(() => { loadComponents(); }, [loadComponents]);

  const saveComponents = useCallback(async (toSave: PageComponent[]) => {
    if (!config) return;
    try {
      setSaveStatus('saving');
      const res = await fetch(buildApiUrl(config.apiEndpoints.saveLayout, pageId), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ components: toSave }),
      });
      if (res.ok) {
        setSaveStatus('saved');
        setHasUnsavedChanges(false);
        setTimeout(() => setSaveStatus('idle'), 2000);
      } else {
        setSaveStatus('error');
      }
    } catch (e) { console.error('Save failed', e); setSaveStatus('error'); }
  }, [pageId, config]);

  const { isOver, setNodeRef } = useDroppable({
    id: 'page-builder-drop-area',
    data: { accepts: ['palette'] },
  });

  const handleComponentDrop = useCallback((type: ComponentType) => {
    if (type !== 'Container') {
      showToast(`"${type}" must be placed inside a Container. Drag it into a container's drop zone.`);
      return;
    }
    setComponents(prev => [...prev, createComponent(type)]);
    markUnsaved();
  }, [markUnsaved, showToast, setComponents]);

  const handleComponentDropIntoContainer = useCallback((type: ComponentType, containerId: string) => {
    const newComp = createComponent(type);
    setComponents(prev => {
      const container = prev.find(c => c.id === containerId);
      if (!container || !isContainerComp(container)) return prev;
      const cProps = container.props as ContainerComponentProps;
      const cols = migrateToColumns(cProps);
      const oldChildIds = new Set(cols.flatMap(c => c.childIds));
      const currentChildren = cols[0]?.childIds.map(id => prev.find(c => c.id === id)).filter(Boolean) as PageComponent[];
      const updatedChildren = [...currentChildren, newComp];
      const newChildIds = updatedChildren.map(c => c.id);
      const withoutOld = prev.filter(c => c.id === containerId || !oldChildIds.has(c.id));
      const updatedCols = cols.map((col, i) => i === 0 ? { ...col, childIds: newChildIds } : col);
      const withUpdated = withoutOld.map(c => c.id !== containerId ? c : {
        ...c,
        props: {
          ...cProps,
          columns: updatedCols,
          childComponentIds: updatedCols.flatMap(col => col.childIds),
        },
      });
      const existingIds = new Set(withUpdated.map(c => c.id));
      const toAppend = updatedChildren.filter(c => !existingIds.has(c.id));
      return [...withUpdated, ...toAppend];
    });
    markUnsaved();
  }, [markUnsaved, setComponents]);

  const handleComponentDropIntoColumn = useCallback((type: ComponentType, containerId: string, columnIndex: number) => {
    const newComp = createComponent(type);
    setComponents(prev => {
      const withNew = [...prev, newComp];
      return withNew.map(comp => {
        if (comp.id !== containerId || !isContainerComp(comp)) return comp;
        const cProps = comp.props as ContainerComponentProps;
        const cols = migrateToColumns(cProps);
        const targetIdx = Math.min(columnIndex, cols.length - 1);
        const updatedCols = cols.map((col, i) => i === targetIdx ? { ...col, childIds: [...col.childIds, newComp.id] } : col);
        return {
          ...comp,
          props: { ...cProps, columns: updatedCols, childComponentIds: updatedCols.flatMap(c => c.childIds) },
        };
      });
    });
    markUnsaved();
  }, [markUnsaved, setComponents]);

  const handleAddComponentToColumn = useCallback((containerId: string, columnIndex: number, type: ComponentType) => {
    const newComp = createComponent(type);
    setComponents(prev => {
      const withNew = [...prev, newComp];
      return withNew.map(comp => {
        if (comp.id !== containerId || !isContainerComp(comp)) return comp;
        const cProps = comp.props as ContainerComponentProps;
        const cols = migrateToColumns(cProps);
        const targetIdx = Math.min(columnIndex, cols.length - 1);
        const updatedCols = cols.map((col, i) => i === targetIdx ? { ...col, childIds: [...col.childIds, newComp.id] } : col);
        return {
          ...comp,
          props: { ...cProps, columns: updatedCols, childComponentIds: updatedCols.flatMap(c => c.childIds) },
        };
      });
    });
    markUnsaved();
  }, [markUnsaved, setComponents]);

  const handleUpdateContainerChildren = useCallback((containerId: string, updatedChildren: PageComponent[]) => {
    setComponents(prev => {
      const container = prev.find(c => c.id === containerId);
      if (!container || !isContainerComp(container)) return prev;
      const cProps = container.props as ContainerComponentProps;
      const oldChildIds = new Set(migrateToColumns(cProps).flatMap(c => c.childIds));
      const newChildIds = updatedChildren.map(c => c.id);
      const withoutOld = prev.filter(c => c.id === containerId || !oldChildIds.has(c.id));
      const cols = migrateToColumns(cProps);
      const updatedCols = cols.map((col, i) => i === 0 ? { ...col, childIds: newChildIds } : col);
      const withUpdated = withoutOld.map(c => c.id !== containerId ? c : {
        ...c,
        props: {
          ...cProps,
          columns: updatedCols,
          childComponentIds: updatedCols.flatMap(col => col.childIds),
        },
      });
      const existingIds = new Set(withUpdated.map(c => c.id));
      const brandNew = updatedChildren.filter(c => !existingIds.has(c.id));
      return [...withUpdated, ...brandNew];
    });
    markUnsaved();
  }, [markUnsaved, setComponents]);

  const handleReorderColumnChildren = useCallback((containerId: string, columnIndex: number, activeId: string, overId: string) => {
    setComponents(prev =>
      prev.map(comp => {
        if (comp.id !== containerId || !isContainerComp(comp)) return comp;
        const cProps = comp.props as ContainerComponentProps;
        const cols = migrateToColumns(cProps);
        const updatedCols = cols.map((col, i) => {
          if (i !== columnIndex) return col;
          const oi = col.childIds.indexOf(activeId);
          const ni = col.childIds.indexOf(overId);
          if (oi === -1 || ni === -1) return col;
          const r = [...col.childIds];
          r.splice(oi, 1);
          r.splice(ni, 0, activeId);
          return { ...col, childIds: r };
        });
        return {
          ...comp,
          props: { ...cProps, columns: updatedCols, childComponentIds: updatedCols.flatMap(c => c.childIds) },
        };
      })
    );
    markUnsaved();
  }, [markUnsaved, setComponents]);

  const updateComponent = useCallback((id: string, newProps: PageComponent['props']) => {
    setComponents(prev => prev.map(c => c.id === id ? { ...c, props: newProps } : c));
    markUnsaved();
    setEditingComponent(null);
  }, [markUnsaved, setComponents]);

  const deleteComponent = useCallback((id: string) => {
    setComponents(prev =>
      prev.filter(c => c.id !== id).map(comp => {
        if (!isContainerComp(comp)) return comp;
        const cProps = comp.props as ContainerComponentProps;
        const cols = migrateToColumns(cProps);
        const updatedCols = cols.map(col => ({ ...col, childIds: col.childIds.filter(cid => cid !== id) }));
        return { ...comp, props: { ...cProps, columns: updatedCols, childComponentIds: updatedCols.flatMap(c => c.childIds) } };
      })
    );
    markUnsaved();
    setComponentToDelete(null);
  }, [markUnsaved, setComponents]);

  const duplicateComponent = useCallback((id: string) => {
    setComponents(prev => {
      const target = prev.find(c => c.id === id);
      if (!target) return prev;
      const { cloned, newChildren } = deepCloneComponent(target, prev);
      const idx = prev.findIndex(c => c.id === id);
      const result = [...prev];
      result.splice(idx + 1, 0, cloned);
      return [...result, ...newChildren];
    });
    markUnsaved();
    showToast('Component duplicated', 'success');
  }, [markUnsaved, showToast, setComponents]);

  const copyToClipboard = useCallback((id: string) => {
    setComponentsRaw(prev => {
      const target = prev.find(c => c.id === id);
      if (!target) return prev;
      const allChildIds = isContainerComp(target) ? migrateToColumns(target.props).flatMap(col => col.childIds) : [];
      const descendants = allChildIds.map(cid => prev.find(c => c.id === cid)).filter(Boolean) as PageComponent[];
      try {
        localStorage.setItem(CLIPBOARD_KEY, JSON.stringify([target, ...descendants]));
        setClipboardEmpty(false);
        showToast('Copied to clipboard', 'success');
      } catch { showToast('Copy failed'); }
      return prev;
    });
  }, [showToast]);

  const pasteFromClipboard = useCallback((insertAfterIndex?: number) => {
    try {
      const raw = localStorage.getItem(CLIPBOARD_KEY);
      if (!raw) { showToast('Clipboard is empty'); return; }
      const payload = JSON.parse(raw) as PageComponent[];
      if (!payload.length) return;

      const idMap = new Map<string, string>();
      const reId = (old: string): string => {
        if (!idMap.has(old)) {
          idMap.set(old, `${old.split('-')[0]}-paste-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`);
        }
        return idMap.get(old)!;
      };

      const remapped = payload.map(comp => {
        const newId = reId(comp.id);
        if (!isContainerComp(comp)) return { ...comp, id: newId };
        const cProps = comp.props as ContainerComponentProps;
        const cols = migrateToColumns(cProps);
        const newCols = cols.map(col => ({
          ...col,
          id: `col-paste-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,
          childIds: col.childIds.map(reId),
        }));
        return {
          ...comp,
          id: newId,
          props: { ...cProps, columns: newCols, childComponentIds: newCols.flatMap(c => c.childIds) },
        };
      });

      setComponents(prev => {
        if (insertAfterIndex === undefined) return [...prev, ...remapped];
        const result = [...prev];
        result.splice(insertAfterIndex + 1, 0, ...remapped);
        return result;
      });

      markUnsaved();
      showToast('Pasted from clipboard', 'success');
    } catch { showToast('Paste failed — clipboard data may be invalid'); }
  }, [markUnsaved, showToast, setComponents]);

  const handleReorder = useCallback((activeId: string, overId: string) => {
    setComponents(prev => {
      const oi = prev.findIndex(c => c.id === activeId);
      const ni = prev.findIndex(c => c.id === overId);
      if (oi === -1 || ni === -1) return prev;
      const updated = [...prev];
      const [moved] = updated.splice(oi, 1);
      updated.splice(ni, 0, moved);
      return updated;
    });
    markUnsaved();
  }, [markUnsaved, setComponents]);

  const findComponent = useCallback((id: string) => components.find(c => c.id === id), [components]);

  const topLevelComponents = components.filter(comp =>
    !components.some(c => {
      if (!isContainerComp(c)) return false;
      const cProps = c.props as ContainerComponentProps;
      return cProps.columns?.some(col => col.childIds.includes(comp.id)) || cProps.childComponentIds?.includes(comp.id);
    })
  );

  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      const ctrl = e.ctrlKey || e.metaKey;
      const tag = (e.target as HTMLElement).tagName;
      if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
      if (ctrl && e.key === 'z' && !e.shiftKey) { e.preventDefault(); undo(); }
      if (ctrl && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) { e.preventDefault(); redo(); }
      if (ctrl && e.key === 's') { e.preventDefault(); saveComponents(components); }
      if (ctrl && e.key === 'v') { e.preventDefault(); pasteFromClipboard(); }
      if (e.key === 'Escape') { setEditingComponent(null); }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [undo, redo, saveComponents, components, pasteFromClipboard]);

  useEffect(() => {
    try { setClipboardEmpty(!localStorage.getItem(CLIPBOARD_KEY)); }
    catch { /* unavailable */ }
  }, []);

  if (!config) return <div className="p-8 text-var-danger">Invalid content type: {contentType}</div>;
  if (isLoading) return <div className="flex items-center justify-center h-64 text-lg text-var-text">Loading builder…</div>;

  return (
    <DndProvider
      items={topLevelComponents.map(c => c.id)}
      onComponentDrop={handleComponentDrop}
      onComponentDropIntoContainer={handleComponentDropIntoContainer}
      onComponentDropIntoColumn={handleComponentDropIntoColumn}
      onReorder={handleReorder}
    >
      <div className="flex h-screen bg-var-surface">

        <ComponentPalette />

        <div className="flex-1 flex flex-col overflow-hidden">

          <div className="bg-var-surface border-b border-var-border px-4 py-3 flex items-center justify-between shrink-0 gap-3">
            <div className="shrink-0">
              <h1 className="text-lg font-bold capitalize text-var-text leading-tight">{title}</h1>
              <p className="text-xs text-var-text-muted">{subtitle}</p>
            </div>

            <div className="flex items-center gap-2 shrink-0">
              <div className="flex items-center bg-var-surface-hover rounded-lg p-0.5">
                <button type="button" onClick={undo} disabled={!canUndo} title="Undo (Ctrl+Z)"
                  className="w-7 h-7 flex items-center justify-center rounded-md text-var-text-muted hover:bg-var-surface hover:text-var-text disabled:opacity-30 disabled:cursor-not-allowed transition-all">
                  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
                  </svg>
                </button>
                <button type="button" onClick={redo} disabled={!canRedo} title="Redo (Ctrl+Y)"
                  className="w-7 h-7 flex items-center justify-center rounded-md text-var-text-muted hover:bg-var-surface hover:text-var-text disabled:opacity-30 disabled:cursor-not-allowed transition-all">
                  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 10H11a8 8 0 00-8 8v2m18-10l-6 6m6-6l-6-6" />
                  </svg>
                </button>
              </div>

              <button type="button" onClick={() => pasteFromClipboard()} disabled={clipboardEmpty}
                title="Paste from clipboard (Ctrl+V)"
                className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded-lg border border-var-border text-var-text-muted hover:border-var-info hover:text-var-info hover:bg-var-info-bg disabled:opacity-30 disabled:cursor-not-allowed transition-all">
                <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
                </svg>
                Paste
              </button>

              {hasUnsavedChanges && (
                <div className="flex items-center gap-1.5">
                  <div className="w-1.5 h-1.5 bg-var-warning rounded-full animate-pulse" />
                  <span className="text-xs text-var-warning font-medium hidden sm:inline">Unsaved</span>
                </div>
              )}
              {saveStatus === 'saving' && <span className="text-var-primary text-xs">Saving…</span>}
              {saveStatus === 'saved' && (
                <span className="text-var-success text-xs flex items-center gap-1">
                  <span className="w-1.5 h-1.5 bg-var-success rounded-full inline-block" /> Saved
                </span>
              )}
              {saveStatus === 'error' && <span className="text-var-danger text-xs">Save failed</span>}

              <button onClick={() => saveComponents(components)}
                disabled={saveStatus === 'saving' || !hasUnsavedChanges}
                title="Save (Ctrl+S)"
                className={`px-4 py-2 rounded-lg font-medium text-sm transition-all ${
                  saveStatus === 'saving' || !hasUnsavedChanges
                    ? 'bg-var-surface-hover text-var-text-muted cursor-not-allowed'
                    : 'bg-var-primary text-white hover:bg-var-primary-hover'
                }`}>
                {saveStatus === 'saving' ? 'Saving…' : 'Save Page'}
              </button>
            </div>
          </div>

          <div ref={setNodeRef} className={`flex-1 overflow-y-auto transition-colors duration-200 ${isOver ? 'bg-var-primary-muted' : 'bg-var-bg'}`}>
            <div className="max-w-5xl mx-auto p-6 space-y-4">
              <div className="flex items-start gap-3 px-4 py-3 bg-var-info-bg border border-var-info-border rounded-xl text-sm text-var-info-text">
                <svg className="w-4 h-4 mt-0.5 shrink-0 text-var-info" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
                <span>
                  <strong className="font-semibold">Container-first</strong> — drag a{' '}
                  <span className="font-mono bg-var-info-bg px-1 rounded text-xs">Container</span>{' '}
                  onto the canvas, then drag any component into it.{' '}
                  <span className="text-var-info-text/60 text-xs">Ctrl+Z undo · Ctrl+Y redo · Ctrl+S save · Ctrl+V paste</span>
                </span>
              </div>

              <PasteZone disabled={clipboardEmpty} onPaste={() => pasteFromClipboard(0)} />

              {topLevelComponents.length === 0 && (
                <div className="text-center py-16">
                  <div className={`border-2 border-dashed rounded-xl p-14 transition-all ${isOver ? 'border-var-primary bg-var-primary-muted' : 'border-var-border bg-var-surface'}`}>
                    {isOver ? (
                      <p className="text-lg font-semibold text-var-primary">Release to add Container</p>
                    ) : (
                      <div className="space-y-3">
                        <div className="flex justify-center">
                          <div className="w-16 h-10 rounded-lg border-2 border-dashed border-var-border flex gap-1 items-stretch p-1.5">
                            <div className="w-4 bg-var-surface-hover rounded-sm" />
                            <div className="flex-1 bg-var-surface-hover/50 rounded-sm" />
                          </div>
                        </div>
                        <p className="text-lg font-semibold text-var-text-muted">Start with a Container</p>
                        <p className="text-sm text-var-text-muted max-w-xs mx-auto">
                          Drag a <span className="font-mono bg-var-surface-hover px-1 rounded">Container</span> from
                          the left palette onto this canvas.
                        </p>
                      </div>
                    )}
                  </div>
                </div>
              )}

              {topLevelComponents.map((comp, idx) => (
                <div key={comp.id} className="space-y-4">
                  <ComponentWrapper
                    component={comp}
                    allComponents={components}
                    onEdit={setEditingComponent}
                    onDelete={id => setComponentToDelete(id)}
                    onDuplicate={duplicateComponent}
                    onCopy={copyToClipboard}
                    onUpdateContainerChildren={handleUpdateContainerChildren}
                    onAddComponentToColumn={handleAddComponentToColumn}
                    onReorderColumnChildren={handleReorderColumnChildren}
                  />
                  <PasteZone disabled={clipboardEmpty} onPaste={() => pasteFromClipboard(idx + 1)} />
                </div>
              ))}

              <div className={`border-2 border-dashed rounded-xl py-5 text-center transition-all ${
                isOver
                  ? 'border-var-primary bg-var-primary-muted text-var-primary'
                  : 'border-var-border text-var-text-muted hover:border-var-border-strong hover:text-var-text'
              }`}>
                <p className="text-sm font-medium">
                  {isOver ? 'Release to add Container' : '+ Drag a Container here to add a new row'}
                </p>
              </div>
            </div>
          </div>
        </div>

        <ModalEditPanel
          component={findComponent(editingComponent ?? '') ?? null}
          onSave={updateComponent}
          onClose={() => setEditingComponent(null)}
        />

        <DeleteConfirmationModal
          isOpen={componentToDelete !== null}
          onConfirm={() => componentToDelete && deleteComponent(componentToDelete)}
          onCancel={() => setComponentToDelete(null)}
          componentName={findComponent(componentToDelete ?? '')?.type ?? 'component'}
        />

        <ToastList toasts={toasts} />
      </div>
    </DndProvider>
  );
}