// app/components/admin/blocks/Container.tsx
'use client';

import React, { useEffect, useState } from 'react';
import {
  ContainerComponentProps,
  LAYOUT_DEFINITIONS,
  migrateToColumns,
} from '@/lib/page-builder/types';
import { SidebarWidget } from '@/lib/page-builder/container-types';
import { renderSidebarWidget } from '@/lib/page-builder/sidebar-widget-registry';
import { componentRegistry } from '@/lib/page-builder/component-registry';
import { ComponentType } from '@/lib/page-builder/component-registry';
import { useDroppable } from '@dnd-kit/core';

// ── Sidebar hook ──────────────────────────────────────────────────────────────

function useSidebarWidgets(
  savedSidebarId: string | null | undefined,
  inlineWidgets: SidebarWidget[]
): { widgets: SidebarWidget[]; loading: boolean } {
  const [widgets, setWidgets] = useState<SidebarWidget[]>(
    savedSidebarId ? [] : inlineWidgets
  );
  const [loading, setLoading] = useState(!!savedSidebarId);

  useEffect(() => {
    if (!savedSidebarId) {
      setWidgets(inlineWidgets);
      setLoading(false);
      return;
    }
    let active = true;
    setLoading(true);
    fetch(`/api/backend/admin/sidebars/${savedSidebarId}`)
      .then(r => (r.ok ? r.json() : Promise.reject()))
      .then(data => { if (active) setWidgets(Array.isArray(data.sidebar?.widgets) ? data.sidebar.widgets : []); })
      .catch(() => { if (active) setWidgets(inlineWidgets); })
      .finally(() => { if (active) setLoading(false); });
    return () => { active = false; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [savedSidebarId]);

  return { widgets, loading };
}

// ── Padding helper ────────────────────────────────────────────────────────────

function resolvePadding(props: ContainerComponentProps, side: 'top' | 'right' | 'bottom' | 'left'): number {
  if (side === 'top')    return props.paddingTop    ?? props.paddingY ?? 16;
  if (side === 'bottom') return props.paddingBottom ?? props.paddingY ?? 16;
  if (side === 'right')  return props.paddingRight  ?? props.paddingX ?? 16;
  return                        props.paddingLeft   ?? props.paddingX ?? 16;
}

// ── Component picker modal ────────────────────────────────────────────────────

interface ComponentPickerProps {
  onSelect: (type: ComponentType) => void;
  onClose: () => void;
}

function ComponentPicker({ onSelect, onClose }: ComponentPickerProps) {
  const entries = Object.entries(componentRegistry).filter(
    ([type]) => type !== 'Container'
  ) as [ComponentType, (typeof componentRegistry)[ComponentType]][];

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm"
      onClick={onClose}
    >
      <div
        className="bg-white rounded-2xl shadow-2xl w-full max-w-md mx-4 overflow-hidden"
        onClick={e => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-5 py-4 border-b border-gray-100">
          <div>
            <h3 className="text-sm font-semibold text-gray-900">Add Component</h3>
            <p className="text-xs text-gray-400 mt-0.5">Choose a component to add to this column</p>
          </div>
          <button
            type="button"
            onClick={onClose}
            className="w-7 h-7 flex items-center justify-center rounded-lg text-gray-400 hover:text-gray-600 hover:bg-gray-100 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="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>
        <div className="p-4 max-h-96 overflow-y-auto">
          <div className="grid grid-cols-2 gap-2">
            {entries.map(([type, config]) => (
              <button
                key={type}
                type="button"
                onClick={() => { onSelect(type); onClose(); }}
                className="flex items-start gap-3 p-3 rounded-xl border border-gray-200 hover:border-blue-300 hover:bg-blue-50 transition-all text-left group"
              >
                <span className="text-xl shrink-0 mt-0.5">
                  {(config as { icon?: string }).icon ?? '🔲'}
                </span>
                <div className="min-w-0">
                  <p className="text-xs font-semibold text-gray-800 group-hover:text-blue-700 truncate">{type}</p>
                  <p className="text-xs text-gray-400 truncate leading-relaxed">
                    {(config as { description?: string }).description ?? ''}
                  </p>
                </div>
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Column slot ───────────────────────────────────────────────────────────────
// Each column is a droppable zone — palette items can be dragged directly
// into it, exactly like the ContainerDropZone for full-width/sidebar layouts.

interface ColumnSlotProps {
  containerId: string;
  columnIndex: number;
  columnId: string;
  children: React.ReactNode;
  isEmpty: boolean;
  onAddComponent: (columnIndex: number) => void;
}

function ColumnSlot({
  containerId,
  columnIndex,
  children,
  isEmpty,
  onAddComponent,
}: ColumnSlotProps) {
  // Register this column as a droppable target.
  // DndProvider checks for ids starting with "column-drop-" and routes the
  // palette drop to handleComponentDropIntoColumn in PageBuilder.
  const { isOver, setNodeRef } = useDroppable({
    id:   `column-drop-${containerId}-${columnIndex}`,
    data: { containerId, columnIndex, accepts: ['palette'] },
  });

  return (
    <div
      ref={setNodeRef}
      className={`flex flex-col min-h-30 min-w-0 rounded-xl transition-colors duration-150 ${
        isOver ? 'bg-blue-50 ring-2 ring-blue-400 ring-offset-1' : ''
      }`}
    >
      {/* Palette drag overlay hint */}
      {isOver && (
        <div className="flex items-center justify-center gap-2 py-2 text-blue-600 text-xs font-medium">
          <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="M12 4v16m8-8H4" />
          </svg>
          Drop here
        </div>
      )}

      {/* Existing children */}
      {!isEmpty && (
        <div className="flex flex-col gap-3 mb-3">{children}</div>
      )}

      {/* Empty state — shown when no children and not being dragged over */}
      {isEmpty && !isOver && (
        <div className="flex-1 flex flex-col items-center justify-center gap-2 border-2 border-dashed border-gray-200 rounded-xl p-4 mb-3 bg-gray-50/50">
          <p className="text-xs text-gray-400 text-center">
            Drop a component here or click below
          </p>
        </div>
      )}

      {/* + Add Component button — always visible */}
      <button
        type="button"
        onClick={() => onAddComponent(columnIndex)}
        className="w-full flex items-center justify-center gap-1.5 py-2 px-3 text-xs font-medium text-blue-600 border border-dashed border-blue-300 rounded-lg hover:bg-blue-50 hover:border-blue-400 transition-colors"
      >
        <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="M12 4v16m8-8H4" />
        </svg>
        Add Component
      </button>
    </div>
  );
}

// ── Main Container block ──────────────────────────────────────────────────────

interface ContainerBlockProps extends ContainerComponentProps {
  children?: React.ReactNode;
  onAddComponentToColumn?: (columnIndex: number, type: ComponentType) => void;
  columnChildren?: React.ReactNode[];
}

export default function Container({
  children,
  onAddComponentToColumn,
  columnChildren,
  ...propsRaw
}: ContainerBlockProps) {
  const props = propsRaw as ContainerComponentProps;
  const {
    layout = 'full-width',
    savedSidebarId,
    sidebarWidgets = [],
    sidebarHideOnMobile = false,
    sidebarWidth = 300,
    containerPadding = true,
    maxWidth = 1280,
    containerBackground = 'transparent',
    gap = 32,
  } = props;

  // containerId comes from the id prop spread via {...cp} in ComponentWrapper
  const containerId = (props as ContainerComponentProps & { id: string }).id ?? '';

  const { widgets, loading } = useSidebarWidgets(savedSidebarId, sidebarWidgets);

  const columns = migrateToColumns(props);
  const def     = LAYOUT_DEFINITIONS[layout ?? 'full-width'];

  const [pickerForColumn, setPickerForColumn] = useState<number | null>(null);

  const handleAddComponent = (columnIndex: number) => {
    setPickerForColumn(columnIndex);
  };

  // Side effect BEFORE state update — never put side effects inside updaters
  const handlePickComponent = (type: ComponentType) => {
    if (pickerForColumn !== null && onAddComponentToColumn) {
      onAddComponentToColumn(pickerForColumn, type);
    }
    setPickerForColumn(null);
  };

  const outerStyle: React.CSSProperties = {
    backgroundColor: containerBackground,
  };

  const innerStyle: React.CSSProperties = {
    maxWidth:      containerPadding ? (maxWidth === 9999 ? 'none' : maxWidth) : 'none',
    paddingTop:    resolvePadding(props, 'top'),
    paddingRight:  containerPadding ? resolvePadding(props, 'right')  : 0,
    paddingBottom: resolvePadding(props, 'bottom'),
    paddingLeft:   containerPadding ? resolvePadding(props, 'left')   : 0,
  };

  // ── Sidebar layouts ──────────────────────────────────────────────────────

  if (layout === 'left-sidebar' || layout === 'right-sidebar') {
    const sidebarEl = (
      <aside
        style={{ width: sidebarWidth, minWidth: sidebarWidth }}
        className={`flex-col gap-4 shrink-0 ${sidebarHideOnMobile ? 'hidden md:flex' : 'flex'}`}
      >
        {loading ? (
          [1, 2, 3].map(i => <div key={i} className="h-24 bg-gray-100 rounded-xl animate-pulse" />)
        ) : widgets.length === 0 ? (
          <div className="border-2 border-dashed border-gray-200 rounded-xl p-6 text-center text-gray-400 text-sm">
            No sidebar widgets yet.
          </div>
        ) : (
          widgets.map(w => (
            <div key={w.id} className="bg-white border border-gray-100 rounded-xl p-4 shadow-sm">
              {renderSidebarWidget(w)}
            </div>
          ))
        )}
      </aside>
    );

    const mainEl = (
      <ColumnSlot
        containerId={containerId}
        columnIndex={0}
        columnId={columns[0]?.id ?? 'main'}
        isEmpty={!columnChildren?.[0] && !children}
        onAddComponent={handleAddComponent}
      >
        {columnChildren?.[0] ?? children}
      </ColumnSlot>
    );

    return (
      <div className="w-full" style={outerStyle}>
        <div className="mx-auto w-full" style={innerStyle}>
          <div className="flex gap-8 w-full" style={{ gap }}>
            {layout === 'left-sidebar'  && <>{sidebarEl}{mainEl}</>}
            {layout === 'right-sidebar' && <>{mainEl}{sidebarEl}</>}
          </div>
        </div>
        {pickerForColumn !== null && (
          <ComponentPicker onSelect={handlePickComponent} onClose={() => setPickerForColumn(null)} />
        )}
      </div>
    );
  }

  // ── Multi-column layout ──────────────────────────────────────────────────

  return (
    <div className="w-full" style={outerStyle}>
      <div className="mx-auto w-full" style={innerStyle}>
        <div
          className="grid w-full"
          style={{ gridTemplateColumns: def.fractions.join(' '), gap }}
        >
          {columns.map((col, i) => (
            <ColumnSlot
              key={col.id}
              containerId={containerId}
              columnIndex={i}
              columnId={col.id}
              isEmpty={!columnChildren?.[i]}
              onAddComponent={handleAddComponent}
            >
              {columnChildren?.[i]}
            </ColumnSlot>
          ))}
        </div>
      </div>
      {pickerForColumn !== null && (
        <ComponentPicker onSelect={handlePickComponent} onClose={() => setPickerForColumn(null)} />
      )}
    </div>
  );
}