// components/admin/page-builder/ComponentWrapper.tsx
'use client';

import { useSortable } from '@dnd-kit/sortable';
import {
  DndContext,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
  closestCenter,
} from '@dnd-kit/core';
import {
  SortableContext,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { useEffect, useRef, useState, useMemo } from 'react';
import {
  PageComponent,
  ContainerComponentProps,
  migrateToColumns,
  LAYOUT_DEFINITIONS,
} from '@/lib/page-builder/types';
import { componentRegistry } from '@/lib/page-builder/component-registry';
import { ComponentType } from '@/lib/page-builder/component-registry';
import { ContainerDropZone } from './ContainerDropZone';
import ContainerBlock from '@/app/components/admin/blocks/Container';
import {
  SidebarWidget,
  SavedSidebar,
} from '@/lib/page-builder/container-types';
import { sidebarWidgetRegistry, renderSidebarWidget } from '@/lib/page-builder/sidebar-widget-registry';

// ── Hook: fetch saved sidebar for builder canvas preview ──────────────────────

function useBuilderSidebarPreview(savedSidebarId: string | null | undefined) {
  const [sidebar, setSidebar] = useState<SavedSidebar | null>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [fetchedId, setFetchedId] = useState<string | null | undefined>(undefined);
  const cancelRef = useRef<() => void>(() => {});

  useEffect(() => {
    cancelRef.current();
    if (!savedSidebarId) {
      let active = true;
      cancelRef.current = () => { active = false; };
      Promise.resolve().then(() => {
        if (!active) return;
        setSidebar(null); setFetchedId(null); setLoading(false);
      });
      return () => { active = false; };
    }
    let active = true;
    cancelRef.current = () => { active = false; };
    fetch(`/api/backend/admin/sidebars/${savedSidebarId}`)
      .then(r => r.ok ? r.json() : Promise.reject())
      .then(data => { if (active) { setSidebar(data.sidebar ?? null); setFetchedId(savedSidebarId); setLoading(false); } })
      .catch(() => { if (active) { setSidebar(null); setFetchedId(savedSidebarId); setLoading(false); } });
    return () => { active = false; };
  }, [savedSidebarId]);

  return { sidebar, loading: loading || (!!savedSidebarId && fetchedId !== savedSidebarId) };
}

// ── Builder sidebar panel ─────────────────────────────────────────────────────

function BuilderSidebarPanel({
  savedSidebarId, inlineWidgets, sidebarWidth, sidebarHideOnMobile, onEdit,
}: {
  savedSidebarId?: string | null; inlineWidgets: SidebarWidget[]; sidebarWidth: number;
  sidebarHideOnMobile?: boolean; onEdit: () => void; containerId: string;
}) {
  const { sidebar, loading } = useBuilderSidebarPreview(savedSidebarId);
  const widgets = savedSidebarId ? (sidebar?.widgets ?? []) : inlineWidgets;

  return (
    <aside style={{ width: sidebarWidth, minWidth: sidebarWidth }} className="flex flex-col gap-4 shrink-0">
      <div className="flex items-center justify-between px-3 py-2 bg-var-warning-bg border border-var-warning-border rounded-xl">
        <div className="flex items-center gap-2 min-w-0 flex-wrap">
          <span className="text-sm shrink-0">📐</span>
          {loading ? (
            <span className="text-xs text-var-warning-text animate-pulse">Loading…</span>
          ) : sidebar ? (
            <div className="min-w-0">
              <p className="text-xs font-semibold text-var-warning-text truncate">{sidebar.name}</p>
              <p className="text-xs text-var-warning-text/70">{sidebar.widgets?.length ?? 0} widget{(sidebar.widgets?.length ?? 0) !== 1 ? 's' : ''}</p>
            </div>
          ) : (
            <span className="text-xs text-var-warning-text italic">No sidebar selected</span>
          )}
          {sidebarHideOnMobile ? (
            <span className="text-xs bg-var-warning-bg text-var-warning-text px-1.5 py-0.5 rounded-full">📵 Hidden</span>
          ) : (
            <span className="text-xs bg-var-success-bg text-var-success-text px-1.5 py-0.5 rounded-full">📱 Visible</span>
          )}
        </div>
        <button type="button" onClick={onEdit} className="text-xs text-var-warning-text hover:underline shrink-0 ml-2">Change</button>
      </div>
      {loading ? (
        <div className="space-y-2">{[1,2].map(i => <div key={i} className="h-16 bg-var-surface-hover rounded-xl animate-pulse" />)}</div>
      ) : widgets.length === 0 ? (
        <div className="border-2 border-dashed border-var-border rounded-xl p-5 text-center">
          <p className="text-xs text-var-text-muted">No widgets yet.</p>
          <button type="button" onClick={onEdit} className="mt-2 text-xs text-var-primary hover:underline">
            {savedSidebarId ? 'Edit sidebar →' : 'Select a sidebar →'}
          </button>
        </div>
      ) : (
        <div className="space-y-3 pointer-events-none">
          {widgets.map(w => (
            <div key={w.id} className="bg-var-surface border border-var-border rounded-xl p-3 shadow-var-card">
              <div className="flex items-center gap-2 mb-2 pb-2 border-b border-var-border">
                <span className="text-xs">{sidebarWidgetRegistry[w.type]?.icon}</span>
                <span className="text-xs font-medium text-var-text-muted">{sidebarWidgetRegistry[w.type]?.label ?? w.type}</span>
              </div>
              {renderSidebarWidget(w)}
            </div>
          ))}
        </div>
      )}
    </aside>
  );
}

// ── Column children with inner sortable DnD ───────────────────────────────────

interface ColumnChildrenProps {
  containerId: string;
  columnIndex: number;
  childIds: string[];
  componentMap: Map<string, PageComponent>;
  allComponents: PageComponent[];
  onEdit: (id: string) => void;
  onDelete: (id: string) => void;
  onDuplicate: (id: string) => void;
  onCopy: (id: string) => void;
  onUpdateContainerChildren: (containerId: string, updated: PageComponent[]) => void;
  onAddComponentToColumn: (containerId: string, columnIndex: number, type: ComponentType) => void;
  onReorderColumnChildren: (containerId: string, columnIndex: number, activeId: string, overId: string) => void;
}

function ColumnChildren({
  containerId, columnIndex, childIds, componentMap, allComponents,
  onEdit, onDelete, onDuplicate, onCopy,
  onUpdateContainerChildren, onAddComponentToColumn, onReorderColumnChildren,
}: ColumnChildrenProps) {
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 5 } }));

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || active.id === over.id) return;
    onReorderColumnChildren(containerId, columnIndex, active.id as string, over.id as string);
  };

  if (childIds.length === 0) return null;

  return (
    <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <SortableContext items={childIds} strategy={verticalListSortingStrategy}>
        <div className="flex flex-col gap-3">
          {childIds.map(cid => {
            const child = componentMap.get(cid);
            if (!child) return null;
            return (
              <ComponentWrapper
                key={child.id}
                component={child}
                allComponents={allComponents}
                onEdit={onEdit}
                onDelete={onDelete}
                onDuplicate={onDuplicate}
                onCopy={onCopy}
                onUpdateContainerChildren={onUpdateContainerChildren}
                onAddComponentToColumn={onAddComponentToColumn}
                onReorderColumnChildren={onReorderColumnChildren}
              />
            );
          })}
        </div>
      </SortableContext>
    </DndContext>
  );
}

// ── Action button helper ──────────────────────────────────────────────────────

function ActionBtn({ onClick, title, color, children }: { onClick: () => void; title: string; color: string; children: React.ReactNode }) {
  return (
    <button
      type="button"
      onClick={onClick}
      title={title}
      className={`w-7 h-7 ${color} text-white rounded-lg flex items-center justify-center text-xs transition-colors shadow-var-card`}
    >
      {children}
    </button>
  );
}

// ── Main ComponentWrapper ─────────────────────────────────────────────────────

interface ComponentWrapperProps {
  component: PageComponent;
  allComponents: PageComponent[];
  onEdit: (id: string) => void;
  onDelete: (id: string) => void;
  onDuplicate: (id: string) => void;
  onCopy: (id: string) => void;
  onUpdateContainerChildren: (containerId: string, updatedChildren: PageComponent[]) => void;
  onAddComponentToColumn: (containerId: string, columnIndex: number, type: ComponentType) => void;
  onReorderColumnChildren: (containerId: string, columnIndex: number, activeId: string, overId: string) => void;
}

export function ComponentWrapper({
  component, allComponents,
  onEdit, onDelete, onDuplicate, onCopy,
  onUpdateContainerChildren, onAddComponentToColumn, onReorderColumnChildren,
}: ComponentWrapperProps) {
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } =
    useSortable({ id: component.id });
  const style = { transform: CSS.Transform.toString(transform), transition };

  const componentMap = useMemo(() => {
    const m = new Map<string, PageComponent>();
    for (const c of allComponents) m.set(c.id, c);
    return m;
  }, [allComponents]);

  // ── Container ──────────────────────────────────────────────────────────────

  if (component.type === 'Container') {
    const cp = component.props as ContainerComponentProps;
    const {
      layout = 'full-width', savedSidebarId, sidebarWidgets = [],
      sidebarWidth = 300, sidebarHideOnMobile = false,
    } = cp;

    const columns = migrateToColumns(cp);
    const def = LAYOUT_DEFINITIONS[layout];
    const isSidebar = layout === 'left-sidebar' || layout === 'right-sidebar';
    const isFullWidth = layout === 'full-width';
    const isMultiCol = !isSidebar && !isFullWidth;

    const totalChildren = columns.reduce((sum, col) => sum + col.childIds.length, 0);

    const legacyChildComponents = columns[0]?.childIds
      .map(cid => componentMap.get(cid)).filter(Boolean) as PageComponent[];

    const mainDropZone = (
      <ContainerDropZone
        containerId={component.id}
        childComponents={legacyChildComponents}
        onChildrenChange={updated => onUpdateContainerChildren(component.id, updated)}
        onEditChild={onEdit}
      />
    );

    const sidebarPanel = (
      <BuilderSidebarPanel
        savedSidebarId={savedSidebarId} inlineWidgets={sidebarWidgets}
        sidebarWidth={sidebarWidth} sidebarHideOnMobile={sidebarHideOnMobile}
        onEdit={() => onEdit(component.id)} containerId={component.id}
      />
    );

    const columnChildren = isMultiCol
      ? columns.map((col, i) => (
          <ColumnChildren
            key={col.id}
            containerId={component.id}
            columnIndex={i}
            childIds={col.childIds}
            componentMap={componentMap}
            allComponents={allComponents}
            onEdit={onEdit}
            onDelete={onDelete}
            onDuplicate={onDuplicate}
            onCopy={onCopy}
            onUpdateContainerChildren={onUpdateContainerChildren}
            onAddComponentToColumn={onAddComponentToColumn}
            onReorderColumnChildren={onReorderColumnChildren}
          />
        ))
      : undefined;

    return (
      <div
        ref={setNodeRef}
        style={style}
        className={`relative border-2 rounded-xl transition-colors ${
          isDragging ? 'border-var-primary opacity-50' : 'border-var-primary/40 hover:border-var-primary bg-var-primary-muted/20'
        }`}
      >
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-2.5 bg-var-surface border-b border-var-primary/30 rounded-t-xl">
          <div className="flex items-center gap-2 flex-wrap">
            <span className="text-base">🗂️</span>
            <span className="text-sm font-semibold text-var-primary">Container</span>
            <span className="text-xs bg-var-primary-muted text-var-primary-text px-2 py-0.5 rounded-full">{def.label}</span>
            {isMultiCol && (
              <span className="flex gap-0.5">
                {def.percentages.map((p, i) => (
                  <span key={i} className="text-xs bg-var-primary-muted text-var-primary-text px-1.5 py-0.5 rounded font-mono">{p}</span>
                ))}
              </span>
            )}
            <span className="text-xs text-var-text-muted">{totalChildren} component{totalChildren !== 1 ? 's' : ''}</span>
            {savedSidebarId && <span className="text-xs bg-var-warning-bg text-var-warning-text px-2 py-0.5 rounded-full">📐 Sidebar linked</span>}
            {sidebarHideOnMobile && isSidebar && <span className="text-xs bg-var-warning-bg text-var-warning-text px-2 py-0.5 rounded-full">📵 Hidden on mobile</span>}
          </div>
          <div className="flex items-center gap-1">
            <ActionBtn onClick={() => onEdit(component.id)} title="Edit" color="bg-var-primary hover:bg-var-primary-hover">✏️</ActionBtn>
            <ActionBtn onClick={() => onDuplicate(component.id)} title="Duplicate" color="bg-var-info hover:bg-var-info-hover">⧉</ActionBtn>
            <ActionBtn onClick={() => onCopy(component.id)} title="Copy to clipboard" color="bg-var-success hover:bg-var-success-hover">📋</ActionBtn>
            <ActionBtn onClick={() => onDelete(component.id)} title="Delete" color="bg-var-danger hover:bg-var-danger-hover">🗑️</ActionBtn>
            <button
              type="button" {...attributes} {...listeners}
              title="Drag to reorder"
              className="w-7 h-7 bg-var-text-muted hover:bg-var-text text-white rounded-lg flex items-center justify-center text-xs cursor-grab active:cursor-grabbing transition-colors shadow-var-card"
            >⠿</button>
          </div>
        </div>

        {/* Body */}
        <div className="p-4">
          {isFullWidth && <div className="w-full">{mainDropZone}</div>}
          {layout === 'left-sidebar' && <div className="flex gap-6">{sidebarPanel}<div className="flex-1 min-w-0">{mainDropZone}</div></div>}
          {layout === 'right-sidebar' && <div className="flex gap-6"><div className="flex-1 min-w-0">{mainDropZone}</div>{sidebarPanel}</div>}
          {isMultiCol && (
            <ContainerBlock
              {...cp}
              id={component.id}
              columnChildren={columnChildren}
              onAddComponentToColumn={(columnIndex, type) =>
                onAddComponentToColumn(component.id, columnIndex, type)
              }
            />
          )}
        </div>
      </div>
    );
  }

  // ── Regular component ──────────────────────────────────────────────────────

  const Component = componentRegistry[component.type]?.component;
  if (!Component) return <div className="text-var-danger">Component {component.type} not found</div>;

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={`relative group border-2 rounded-lg transition-colors ${
        isDragging ? 'border-var-primary opacity-50' : 'border-transparent hover:border-var-primary/40'
      }`}
    >
      <div className="absolute top-2 right-2 flex gap-1.5 opacity-0 group-hover:opacity-100 transition-opacity z-50">
        <ActionBtn onClick={() => onEdit(component.id)} title="Edit" color="bg-var-primary hover:bg-var-primary-hover">✏️</ActionBtn>
        <ActionBtn onClick={() => onDuplicate(component.id)} title="Duplicate" color="bg-var-info hover:bg-var-info-hover">⧉</ActionBtn>
        <ActionBtn onClick={() => onCopy(component.id)} title="Copy to clipboard" color="bg-var-success hover:bg-var-success-hover">📋</ActionBtn>
        <ActionBtn onClick={() => onDelete(component.id)} title="Delete" color="bg-var-danger hover:bg-var-danger-hover">🗑️</ActionBtn>
        <button
          type="button" {...attributes} {...listeners}
          className="w-7 h-7 bg-var-text-muted hover:bg-var-text text-white rounded-lg flex items-center justify-center text-xs cursor-grab active:cursor-grabbing transition-colors shadow-var-card"
          title="Drag"
        >⠿</button>
      </div>
      <div className="pointer-events-none">
        {/* @ts-expect-error dynamic props */}
        <Component {...component.props} />
      </div>
    </div>
  );
}