import { useCallback } from 'react';
import { BlockDefinition, BlockShape, CATEGORY_COLORS, CATEGORY_ICONS } from '../../types/blocks';

interface BlockPaletteProps {
  categories: string[];
  activeCategory: string | null;
  onCategoryChange: (category: string) => void;
  blocksByCategory: Map<string, BlockDefinition[]>;
  blocks: BlockDefinition[];
}

const CATEGORY_LABELS: Record<string, string> = {
  variables: 'Variables',
  logic: 'Logic',
  loops: 'Loops',
  functions: 'Functions',
  events: 'Events',
  dom: 'DOM',
  css: 'CSS',
  html: 'HTML',
  types: 'Types',
  electron: 'Electron',
  ipc: 'IPC',
  dialog: 'Dialogs',
  xaml: 'XAML',
  csharp: 'C#',
  maui: '.NET MAUI',
  node_fs: 'File System',
  node_http: 'HTTP',
  node_express: 'Express',
  node_db: 'Database',
  node_async: 'Async',
  data: 'Data',
  math: 'Math',
  text: 'Text',
  input_output: 'I/O',
};

const COMPACT_SHAPE_CLASS: Record<BlockShape, string> = {
  hat: 'hat',
  stack: '',
  boolean: 'boolean',
  reporter: 'reporter',
  'c-block': '',
  cap: 'cap',
};

function truncate(s: string, n: number) {
  if (typeof s !== 'string') return String(s ?? '');
  return s.length > n ? s.slice(0, n) + '…' : s;
}

function renderMiniInput(field: any, value: any): string {
  if (value === undefined || value === null || value === '') return field.label;
  switch (field.type) {
    case 'boolean': return value ? '✓' : '✗';
    case 'select':
      const opt = field.options?.find((o: any) => o.value === value);
      return truncate(opt?.label || String(value), 14);
    case 'textarea':
    case 'code':
      return truncate(String(value), 18);
    default:
      return truncate(String(value), 18);
  }
}

function MiniBlock({ block }: { block: BlockDefinition }) {
  const color = block.color || CATEGORY_COLORS[block.category] || '#6366f1';
  const shape = block.shape || 'stack';
  const shapeClass = COMPACT_SHAPE_CLASS[shape];
  const cfg = block.config || [];

  // For reporters/booleans show 1 input
  if (shape === 'reporter' || shape === 'boolean') {
    const f = cfg[0];
    return (
      <div
        className={`palette-block-compact ${shapeClass}`}
        style={{ '--block-color': color, backgroundColor: color } as React.CSSProperties}
        title={block.description}
      >
        {block.icon && <span>{block.icon}</span>}
        <span style={{ opacity: 0.9 }}>{block.label}</span>
        {f && <span className="palette-input">{renderMiniInput(f, f.default)}</span>}
      </div>
    );
  }

  // For hat, show label + 1 input
  if (shape === 'hat') {
    const f = cfg[0];
    return (
      <div
        className={`palette-block-compact ${shapeClass}`}
        style={{ '--block-color': color, backgroundColor: color } as React.CSSProperties}
        title={block.description}
      >
        {block.icon && <span>{block.icon}</span>}
        <span>{block.label}</span>
        {f && <span className="palette-input">{renderMiniInput(f, f.default)}</span>}
      </div>
    );
  }

  // For stack/hat/c-block/cap: show label + 1-2 inputs
  const inputs = cfg.slice(0, 2);
  return (
    <div
      className={`palette-block-compact ${shapeClass}`}
      style={{ '--block-color': color, backgroundColor: color } as React.CSSProperties}
      title={block.description}
    >
      {block.icon && <span>{block.icon}</span>}
      <span>{block.label}</span>
      {inputs.map((f, i) => (
        <span key={i} className="palette-input">{renderMiniInput(f, f.default)}</span>
      ))}
    </div>
  );
}

export default function BlockPalette({
  categories,
  activeCategory,
  onCategoryChange,
  blocks,
}: BlockPaletteProps) {
  return (
    <div className="flex h-full">
      {/* Category Tabs (vertical strip on left) - Scratch-style colored circles */}
      <div className="palette-tabs">
        {categories.map((cat) => {
          const color = CATEGORY_COLORS[cat] || '#6366f1';
          const icon = CATEGORY_ICONS[cat] || '■';
          const isActive = activeCategory === cat;
          return (
            <button
              key={cat}
              onClick={() => onCategoryChange(cat)}
              className={`palette-tab ${isActive ? 'palette-tab-active' : ''}`}
              style={{
                backgroundColor: color,
                color: '#fff',
                '--cat-color': color,
              } as React.CSSProperties}
              title={CATEGORY_LABELS[cat] || cat}
            >
              <span>{icon}</span>
              <span className="palette-tab-label">{CATEGORY_LABELS[cat] || cat}</span>
            </button>
          );
        })}
      </div>

      {/* Block List - shows actual block shapes */}
      <div className="palette-block-list">
        {activeCategory && (
          <div
            className="palette-category-header"
            style={{ color: CATEGORY_COLORS[activeCategory] || '#6366f1' }}
          >
            {CATEGORY_LABELS[activeCategory] || activeCategory}
          </div>
        )}
        {blocks.map((block) => (
          <BlockCard key={block.id} block={block} />
        ))}
        {blocks.length === 0 && (
          <div className="text-surface-500 text-xs text-center py-8">
            No blocks in this category
          </div>
        )}
      </div>
    </div>
  );
}

function BlockCard({ block }: { block: BlockDefinition }) {
  const handleDragStart = useCallback(
    (event: React.DragEvent) => {
      event.dataTransfer.setData('application/block', JSON.stringify(block));
      event.dataTransfer.effectAllowed = 'move';
    },
    [block]
  );

  return (
    <div
      draggable
      onDragStart={handleDragStart}
      className="palette-block-item"
    >
      <MiniBlock block={block} />
    </div>
  );
}
