// app/components/admin/page-builder/ContainerDropZone.tsx
'use client';
import { useState, useCallback } from 'react';
import {
  DndContext,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
  useDroppable,
  closestCenter,
} from '@dnd-kit/core';
import {
  SortableContext,
  verticalListSortingStrategy,
  useSortable,
  arrayMove,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { PageComponent, ComponentType } from '@/lib/page-builder/types';
import { componentRegistry } from '@/lib/page-builder/component-registry';
import { createComponent } from '@/lib/page-builder/utils';
import { ComponentPickerModal } from './ComponentPickerModal';

// ── Inner sortable child component card ───────────────────────────────────────

interface InnerComponentCardProps {
  component: PageComponent;
  onEdit: (id: string) => void;
  onDelete: (id: string) => void;
  onDuplicate: (id: string) => void;
  onCopy: (id: string) => void;
}

function InnerComponentCard({ component, onEdit, onDelete, onDuplicate, onCopy }: InnerComponentCardProps) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } =
    useSortable({ id: component.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.4 : 1,
  };

  const Comp = componentRegistry[component.type]?.component;

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`relative group border-2 rounded-xl transition-colors ${
        isDragging ? 'border-blue-400 shadow-lg' : 'border-transparent hover:border-blue-200'
      }`}
    >
      {/* Floating controls */}
      <div className="absolute top-2 right-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity z-20">
        <button
          onClick={() => onEdit(component.id)}
          title="Edit"
          className="w-7 h-7 bg-blue-500 hover:bg-blue-600 text-white rounded-lg shadow flex items-center justify-center text-xs transition-colors"
        >✏️</button>
        <button
          onClick={() => onDuplicate(component.id)}
          title="Duplicate"
          className="w-7 h-7 bg-violet-500 hover:bg-violet-600 text-white rounded-lg shadow flex items-center justify-center text-xs transition-colors"
        >⧉</button>
        <button
          onClick={() => onCopy(component.id)}
          title="Copy to clipboard"
          className="w-7 h-7 bg-teal-500 hover:bg-teal-600 text-white rounded-lg shadow flex items-center justify-center text-xs transition-colors"
        >📋</button>
        <button
          onClick={() => onDelete(component.id)}
          title="Remove"
          className="w-7 h-7 bg-red-500 hover:bg-red-600 text-white rounded-lg shadow flex items-center justify-center text-xs transition-colors"
        >🗑️</button>
        <button
          {...attributes}
          {...listeners}
          title="Drag to reorder"
          className="w-7 h-7 bg-gray-500 hover:bg-gray-600 text-white rounded-lg shadow flex items-center justify-center text-xs cursor-grab active:cursor-grabbing transition-colors"
        >⠿</button>
      </div>

      {/* Component type badge */}
      <div className="absolute top-2 left-2 z-20 opacity-0 group-hover:opacity-100 transition-opacity">
        <span className="bg-white/90 backdrop-blur-sm text-gray-600 text-xs font-medium px-2 py-0.5 rounded-full border border-gray-200 shadow-sm">
          {componentRegistry[component.type]?.icon} {component.type}
        </span>
      </div>

      <div className="pointer-events-none overflow-hidden rounded-xl">
        {/* @ts-expect-error dynamic props */}
        {Comp && <Comp {...component.props} />}
      </div>
    </div>
  );
}

// ── Empty drop zone ───────────────────────────────────────────────────────────

function EmptyDropZone({ isOver, onPickerOpen }: { isOver: boolean; onPickerOpen: () => void }) {
  return (
    <div
      className={`flex flex-col items-center justify-center gap-4 min-h-40 rounded-xl border-2 border-dashed transition-all duration-200 ${
        isOver
          ? 'border-blue-400 bg-blue-50 scale-[1.01]'
          : 'border-gray-300 bg-gray-50/50 hover:border-gray-400 hover:bg-gray-50'
      }`}
    >
      <div className={`text-center transition-colors ${isOver ? 'text-blue-600' : 'text-gray-400'}`}>
        <div className="text-3xl mb-2">{isOver ? '✅' : '📦'}</div>
        <p className="text-sm font-medium">
          {isOver ? 'Release to drop here' : 'Drop components here or'}
        </p>
      </div>
      {!isOver && (
        <button
          onClick={onPickerOpen}
          className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg shadow-sm transition-colors"
        >
          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
          </svg>
          Add Component
        </button>
      )}
    </div>
  );
}

// ── Main ContainerDropZone ────────────────────────────────────────────────────

interface ContainerDropZoneProps {
  containerId: string;
  childComponents: PageComponent[];
  onChildrenChange: (updated: PageComponent[]) => void;
  onEditChild: (id: string) => void;
  /** Optional — passed from PageBuilder when used inside full-width/sidebar layouts */
  onDuplicateChild?: (id: string) => void;
  onCopyChild?: (id: string) => void;
}

export function ContainerDropZone({
  containerId,
  childComponents,
  onChildrenChange,
  onEditChild,
  onDuplicateChild,
  onCopyChild,
}: ContainerDropZoneProps) {
  const [pickerOpen, setPickerOpen] = useState(false);

  const { isOver: isPaletteOver, setNodeRef: setDropRef } = useDroppable({
    id:   `container-drop-${containerId}`,
    data: { containerId, accepts: ['palette'] },
  });

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } })
  );

  const handleInnerDragEnd = useCallback((event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;
    const oldIdx = childComponents.findIndex(c => c.id === active.id);
    const newIdx = childComponents.findIndex(c => c.id === over.id);
    if (oldIdx !== -1 && newIdx !== -1) {
      onChildrenChange(arrayMove(childComponents, oldIdx, newIdx));
    }
  }, [childComponents, onChildrenChange]);

  const handleAddFromPicker = useCallback((type: ComponentType) => {
    const newComp = createComponent(type);
    onChildrenChange([...childComponents, newComp]);
  }, [childComponents, onChildrenChange]);

  const handleDelete = useCallback((id: string) => {
    onChildrenChange(childComponents.filter(c => c.id !== id));
  }, [childComponents, onChildrenChange]);

  // Duplicate within the drop zone (creates a copy appended after the original)
  const handleDuplicate = useCallback((id: string) => {
    if (onDuplicateChild) {
      // Delegate to PageBuilder so undo/redo and the flat component list stay in sync
      onDuplicateChild(id);
      return;
    }
    // Fallback: simple local clone (no nested container support)
    const idx    = childComponents.findIndex(c => c.id === id);
    const target = childComponents[idx];
    if (!target) return;
    const newId    = `${target.type.toLowerCase()}-dup-${Date.now()}`;
    const cloned   = { ...target, id: newId };
    const updated  = [...childComponents];
    updated.splice(idx + 1, 0, cloned);
    onChildrenChange(updated);
  }, [childComponents, onChildrenChange, onDuplicateChild]);

  const handleCopy = useCallback((id: string) => {
    onCopyChild?.(id);
  }, [onCopyChild]);

  return (
    <>
      <div
        ref={setDropRef}
        className={`relative min-h-40 rounded-xl transition-all duration-200 ${
          isPaletteOver ? 'ring-2 ring-blue-400 ring-offset-2 bg-blue-50/30' : ''
        }`}
      >
        {isPaletteOver && (
          <div className="absolute inset-0 z-10 flex items-center justify-center rounded-xl bg-blue-50/70 border-2 border-dashed border-blue-400 pointer-events-none">
            <div className="text-blue-600 font-semibold text-sm flex items-center gap-2">
              <span>✅</span> Drop to add inside container
            </div>
          </div>
        )}

        {childComponents.length === 0 ? (
          <EmptyDropZone isOver={isPaletteOver} onPickerOpen={() => setPickerOpen(true)} />
        ) : (
          <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleInnerDragEnd}>
            <SortableContext items={childComponents.map(c => c.id)} strategy={verticalListSortingStrategy}>
              <div className="space-y-4">
                {childComponents.map(comp => (
                  <InnerComponentCard
                    key={comp.id}
                    component={comp}
                    onEdit={onEditChild}
                    onDelete={handleDelete}
                    onDuplicate={handleDuplicate}
                    onCopy={handleCopy}
                  />
                ))}
                <button
                  onClick={() => setPickerOpen(true)}
                  className="w-full flex items-center justify-center gap-2 py-3 border-2 border-dashed border-gray-300 rounded-xl text-gray-500 hover:border-blue-400 hover:text-blue-600 hover:bg-blue-50 transition-all text-sm font-medium"
                >
                  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" />
                  </svg>
                  Add Component
                </button>
              </div>
            </SortableContext>
          </DndContext>
        )}
      </div>

      <ComponentPickerModal
        isOpen={pickerOpen}
        onClose={() => setPickerOpen(false)}
        onPick={handleAddFromPicker}
      />
    </>
  );
}