'use client';

/**
 * Palette — module type picker panel.
 *
 * Iterates MODULE_REGISTRY, groups entries by category, and renders
 * a draggable button per module type using useDraggable({ id: 'palette:' + type }).
 *
 * Also acts as a trash drop target via useDroppable({ id: 'palette-dropzone' }) —
 * dropping an active canvas item onto the palette removes it from the canvas.
 *
 * All interactives are real <button> elements. All styling is token-only.
 */

import { useDroppable, useDraggable } from '@dnd-kit/core';
import { CLIENT_MODULE_REGISTRY } from '@/server/page-layout/client-registry';
import type { ClientModuleDef } from '@/server/page-layout/types';
import { useT } from '@/lib/i18n/react';
import { Button } from '@/components/ui/primitives/Button';
import { Pill } from '@/components/ui/primitives/Pill';

type PaletteEntry = {
  type: string;
  category: ClientModuleDef<unknown>['category'];
};

function groupByCategory(
  registry: typeof CLIENT_MODULE_REGISTRY,
): Map<ClientModuleDef<unknown>['category'], PaletteEntry[]> {
  const groups = new Map<ClientModuleDef<unknown>['category'], PaletteEntry[]>();
  for (const [type, def] of Object.entries(registry)) {
    const cat = def.category;
    if (!groups.has(cat)) groups.set(cat, []);
    groups.get(cat)!.push({ type, category: cat });
  }
  return groups;
}

// ─── Known module label keys (for safe lookup) ────────────────────────────────

export const KNOWN_LABEL_KEYS: Record<string, 1> = {
  'deal-row:auto-scroll': 1,
  'deal-row:for-you': 1,
  'deal-row:near-you': 1,
  'deal-row:hot-deals': 1,
  'deal-row:group-deals': 1,
  'deal-row:whats-left': 1,
  'deal-row:category': 1,
  'deal-row:custom-query': 1,
  banner: 1,
  'vendor-spotlight': 1,
  'static-content': 1,
  'page-hero': 1,
  'rich-text-content': 1,
  'hero:static-page': 1,
  'merchant-grid': 1,
  'merchant-scroll': 1,
  'deal-grid': 1,
  'category-chips': 1,
  'club-stories': 1,
  'greeting-bar': 1,
};

// ─── Category label + tone maps ───────────────────────────────────────────────

const CATEGORY_LABEL_KEYS: Record<
  ClientModuleDef<unknown>['category'],
  'deal_row' | 'banner' | 'vendor_spotlight' | 'static' | 'custom' | 'content'
> = {
  'deal-row': 'deal_row',
  banner: 'banner',
  'vendor-spotlight': 'vendor_spotlight',
  static: 'static',
  custom: 'custom',
  content: 'content',
};

// ─── Single draggable palette item ────────────────────────────────────────────

interface PaletteItemProps {
  type: string;
  category: ClientModuleDef<unknown>['category'];
}

const CATEGORY_PILL_TONE: Record<
  ClientModuleDef<unknown>['category'],
  'neutral' | 'info' | 'success' | 'warning' | 'danger'
> = {
  'deal-row': 'info',
  banner: 'warning',
  'vendor-spotlight': 'success',
  static: 'neutral',
  custom: 'neutral',
  content: 'neutral',
};

function PaletteItem({ type, category }: PaletteItemProps) {
  const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
    id: `palette:${type}`,
    data: { kind: 'palette', type },
  });
  const tLabels = useT('module_labels');
  const tOrg = useT('page_organizer');
  const categoryLabels = tOrg(
    'module_categories' as Parameters<typeof tOrg>[0],
  ) as unknown as Record<string, string>;

  const label = type in KNOWN_LABEL_KEYS ? tLabels(type as Parameters<typeof tLabels>[0]) : type;
  const catLabel = categoryLabels[CATEGORY_LABEL_KEYS[category]] ?? category;

  return (
    <li>
      <Button
        ref={setNodeRef}
        variant="ghost"
        size="sm"
        {...attributes}
        {...listeners}
        aria-pressed={isDragging}
        className={[
          'w-full rounded-md border px-3 py-2 text-start text-sm',
          'transition-colors focus-visible:ring-2 focus-visible:outline-none',
          'focus-visible:ring-brand-primary-500 focus-visible:ring-offset-2',
          isDragging
            ? 'border-brand-primary-400 bg-brand-primary-50 text-brand-primary-700 opacity-60'
            : 'bg-surface-base text-text-primary hover:border-brand-primary-300 hover:bg-surface-raised border-border-default',
        ].join(' ')}
        data-module-type={type}
      >
        <span className="flex items-center justify-between gap-2">
          <span data-diag={!(type in KNOWN_LABEL_KEYS) ? '' : undefined}>{label}</span>
          <Pill tone={CATEGORY_PILL_TONE[category]} size="sm" aria-label={catLabel}>
            {catLabel}
          </Pill>
        </span>
      </Button>
    </li>
  );
}

// ─── Category group ────────────────────────────────────────────────────────────

interface CategoryGroupProps {
  category: ClientModuleDef<unknown>['category'];
  entries: PaletteEntry[];
}

function CategoryGroup({ category, entries }: CategoryGroupProps) {
  const tOrg = useT('page_organizer');
  const categoryLabels = tOrg('module_categories' as Parameters<typeof tOrg>[0]) as unknown as {
    deal_row: string;
    banner: string;
    vendor_spotlight: string;
    static: string;
    custom: string;
    content: string;
  };
  const catLabel = categoryLabels[CATEGORY_LABEL_KEYS[category]];

  return (
    <div className="flex flex-col gap-1.5">
      <p
        className="text-text-muted ps-1 text-xs font-medium tracking-wide uppercase"
        aria-hidden="true"
      >
        {catLabel}
      </p>
      <ol className="flex flex-col gap-1">
        {entries.map((e) => (
          <PaletteItem key={e.type} type={e.type} category={e.category} />
        ))}
      </ol>
    </div>
  );
}

// ─── Palette (palette-dropzone = trash) ───────────────────────────────────────

export function Palette() {
  const t = useT('page_organizer');
  const { setNodeRef, isOver } = useDroppable({ id: 'palette-dropzone' });

  const groups = groupByCategory(CLIENT_MODULE_REGISTRY);

  return (
    <section
      ref={setNodeRef}
      aria-label={t('palette_heading')}
      className={[
        'flex flex-col gap-4 rounded-md border p-4',
        'transition-colors',
        isOver ? 'border-danger-400 bg-danger-50' : 'bg-surface-base border-border-default',
      ].join(' ')}
    >
      <h2 className="text-text-primary text-sm font-semibold">{t('palette_heading')}</h2>

      {[...groups.entries()].map(([cat, entries]) => (
        <CategoryGroup key={cat} category={cat} entries={entries} />
      ))}

      {isOver && (
        <p role="status" aria-live="polite" className="text-danger-700 mt-auto text-center text-sm">
          {t('btn_delete')} ↓
        </p>
      )}
    </section>
  );
}
