import React, { useState, useRef, useEffect, useCallback } from 'react';
import type { CBNode } from '../../types';
import type { EditorStore } from '../../store/editorStore';
import { WIDGET_REGISTRY, type WidgetPaletteGroup } from '../../widgets/registry';

const CATEGORIES = ['All', 'Basic', 'Media', 'Forms', 'Marketing', 'Content', 'Effects', 'Utility', 'Interactive', 'Social', 'WooCommerce'] as const;
type Category = (typeof CATEGORIES)[number];

interface BlockEntry {
  type: string;
  label: string;
  icon: string;
  category: Exclude<Category, 'All'>;
  description: string;
  color: string;
  defaultNode: Partial<CBNode>;
}

// Registry palette group → Block-picker category. The picker never listed
// structural (Layout) widgets, so those map to null and are excluded — exactly
// as before. Effects/Utility/etc. (new schema-widget groups) map to a sensible
// existing tab so new widgets are still findable. This mapping is the ONLY
// place the picker's fixed category vocabulary meets the richer registry one.
const GROUP_TO_CATEGORY: Record<WidgetPaletteGroup, Exclude<Category, 'All'> | null> = {
  Layout: null,
  Basic: 'Basic',
  // The picker has its own fixed category list and no Navigation tab; folding
  // nav widgets into Basic keeps them findable here while the Elements panel
  // still shows them under their own Navigation tab.
  Navigation: 'Basic',
  Media: 'Media',
  Marketing: 'Marketing',
  Content: 'Content',
  Forms: 'Forms',
  WooCommerce: 'WooCommerce',
  Interactive: 'Interactive',
  Utility: 'Utility',
  Effects: 'Effects',
  Social: 'Social',
  Theme: 'Content',
};

// Derived from the single-source-of-truth registry (src/widgets/registry.ts).
// Produces the same BlockEntry shape the rest of this file already consumes.
// Layout-group widgets are excluded to match the picker's original contents.
const REGISTRY_BLOCKS: BlockEntry[] = WIDGET_REGISTRY.flatMap((w) => {
  const category = GROUP_TO_CATEGORY[w.category];
  if (!category) return [];
  return [{
    type: w.type,
    label: w.label,
    icon: w.icon,
    category,
    description: w.description,
    color: w.color,
    defaultNode: w.defaultNode,
  }];
});

// WooCommerce quick-inserts. These were hand-authored duplicate-type entries
// (all type:'shortcode') so they can't live in the type-keyed registry — kept
// verbatim here, appended after the registry-derived blocks exactly as before.
const WC_BLOCKS: BlockEntry[] = [
  { type: 'shortcode', label: 'WC Products',  icon: '⊡',    category: 'WooCommerce',  description: 'WooCommerce product grid',         color: '#9ca3af', defaultNode: { type: 'shortcode', content: { shortcode: '[products limit="12" columns="3"]' } } },
  { type: 'shortcode', label: 'WC Cart',      icon: '⊟',    category: 'WooCommerce',  description: 'WooCommerce shopping cart',        color: '#9ca3af', defaultNode: { type: 'shortcode', content: { shortcode: '[woocommerce_cart]' } } },
  { type: 'shortcode', label: 'WC Checkout',  icon: '⊠',    category: 'WooCommerce',  description: 'WooCommerce checkout page',        color: '#9ca3af', defaultNode: { type: 'shortcode', content: { shortcode: '[woocommerce_checkout]' } } },
  { type: 'shortcode', label: 'WC My Account', icon: '⊙',   category: 'WooCommerce',  description: 'WooCommerce account page',         color: '#9ca3af', defaultNode: { type: 'shortcode', content: { shortcode: '[woocommerce_my_account]' } } },
];

const BLOCKS: BlockEntry[] = [...REGISTRY_BLOCKS, ...WC_BLOCKS];

interface Props {
  store: EditorStore;
  parentId?: string;
  sectionId?: string;
  onClose?: () => void;
  newSectionAfter?: string | null;
}

export function BlockPicker({ store, parentId, sectionId, onClose, newSectionAfter }: Props) {
  const [query, setQuery] = useState('');
  const [activeCategory, setActiveCategory] = useState<Category>('All');
  const [focusIdx, setFocusIdx] = useState(0);
  const searchRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    const timer = setTimeout(() => searchRef.current?.focus(), 40);
    return () => clearTimeout(timer);
  }, []);

  const filtered = BLOCKS.filter((b) => {
    const matchesCat   = activeCategory === 'All' || b.category === activeCategory;
    const q            = query.toLowerCase();
    const matchesQuery = !q || b.label.toLowerCase().includes(q) || b.description.toLowerCase().includes(q);
    return matchesCat && matchesQuery;
  });

  useEffect(() => { setFocusIdx(0); }, [query, activeCategory]);

  const handleAdd = useCallback(
    (block: BlockEntry) => {
      if (newSectionAfter !== undefined) {
        store.addElementInNewSection(newSectionAfter ?? undefined, block.defaultNode);
      } else if (sectionId) {
        store.addElementInContainer(sectionId, block.defaultNode);
      } else if (parentId) {
        store.addElement(parentId, block.defaultNode);
      } else {
        store.addSection();
      }
      onClose?.();
    },
    [store, parentId, sectionId, onClose, newSectionAfter]
  );

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      setFocusIdx((i) => Math.min(i + 1, filtered.length - 1));
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setFocusIdx((i) => Math.max(i - 1, 0));
    } else if (e.key === 'Enter') {
      e.preventDefault();
      if (filtered[focusIdx]) handleAdd(filtered[focusIdx]);
    } else if (e.key === 'Escape') {
      onClose?.();
    }
  };

  return (
    <div className="jalpi-block-picker" onKeyDown={handleKeyDown}>
      {/* Search */}
      <div className="jalpi-block-picker__search">
        <svg
          className="jalpi-block-picker__search-icon"
          width="14" height="14" viewBox="0 0 24 24"
          fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"
        >
          <circle cx="11" cy="11" r="8"/>
          <path d="m21 21-4.35-4.35"/>
        </svg>
        <input
          ref={searchRef}
          className="jalpi-block-picker__search-input"
          type="text"
          placeholder="Search elements…"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
        {onClose && (
          <button className="jalpi-block-picker__close" onClick={onClose} title="Close (Esc)">
            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
              <path d="M18 6L6 18M6 6l12 12"/>
            </svg>
          </button>
        )}
      </div>

      {/* Category tabs */}
      <div className="jalpi-block-picker__cats">
        {CATEGORIES.map((cat) => (
          <button
            key={cat}
            className={`jalpi-block-picker__cat${activeCategory === cat ? ' is-active' : ''}`}
            onClick={() => setActiveCategory(cat)}
          >
            {cat}
          </button>
        ))}
      </div>

      {/* Element list */}
      <div className="jalpi-block-picker__list">
        {filtered.length === 0 ? (
          <div className="jalpi-block-picker__empty">No elements match "{query}"</div>
        ) : (
          filtered.map((block, i) => (
            <button
              key={`${block.label}__${block.category}`}
              className={`jalpi-block-picker__item${i === focusIdx ? ' is-focused' : ''}`}
              onClick={() => handleAdd(block)}
              onMouseEnter={() => setFocusIdx(i)}
              title={`Add ${block.label}`}
            >
              <span
                className="jalpi-block-picker__icon-wrap"
                style={{ '--block-color': block.color } as React.CSSProperties}
              >
                <span className="jalpi-block-picker__icon">{block.icon}</span>
              </span>
              <span className="jalpi-block-picker__meta">
                <span className="jalpi-block-picker__label">{block.label}</span>
                <span className="jalpi-block-picker__desc">{block.description}</span>
              </span>
              <span className="jalpi-block-picker__cat-badge">{block.category}</span>
            </button>
          ))
        )}
      </div>
    </div>
  );
}

export { BLOCKS };
