// DraftLab.jsx — Draft Lab (beta) screen
const { useState, useEffect, useMemo, useCallback } = React;
const { useApp } = window;

// SVG Icons for Duplicate and Delete
function LabDuplicateIcon({ size = 15, color = 'var(--text-muted)' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}>
      <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
      <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
    </svg>
  );
}

function LabTrashIcon({ size = 15, color = '#E85555' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}>
      <polyline points="3 6 5 6 21 6" />
      <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
      <line x1="10" y1="11" x2="10" y2="17" />
      <line x1="14" y1="11" x2="14" y2="17" />
    </svg>
  );
}

// Reuse the existing 20-step sequence from DraftSimulator
function getDraftStepList() {
  const seq = window.DRAFT_SEQUENCE || [
    { team: 'blue', action: 'ban', slot: 0 },
    { team: 'red',  action: 'ban', slot: 0 },
    { team: 'blue', action: 'ban', slot: 1 },
    { team: 'red',  action: 'ban', slot: 1 },
    { team: 'blue', action: 'ban', slot: 2 },
    { team: 'red',  action: 'ban', slot: 2 },

    { team: 'blue', action: 'pick', slot: 0 },
    { team: 'red',  action: 'pick', slot: 0 },
    { team: 'red',  action: 'pick', slot: 1 },
    { team: 'blue', action: 'pick', slot: 1 },
    { team: 'blue', action: 'pick', slot: 2 },
    { team: 'red',  action: 'pick', slot: 2 },

    { team: 'red',  action: 'ban', slot: 3 },
    { team: 'blue', action: 'ban', slot: 3 },
    { team: 'red',  action: 'ban', slot: 4 },
    { team: 'blue', action: 'ban', slot: 4 },

    { team: 'red',  action: 'pick', slot: 3 },
    { team: 'blue', action: 'pick', slot: 3 },
    { team: 'blue', action: 'pick', slot: 4 },
    { team: 'red',  action: 'pick', slot: 4 },
  ];

  return seq.map((step, idx) => {
    const prefix = step.team === 'blue' ? 'B' : 'R';
    const key = step.action === 'ban' ? `${prefix}B${step.slot + 1}` : `${prefix}${step.slot + 1}`;
    const phase = idx < 6 ? 1 : idx < 12 ? 2 : idx < 16 ? 3 : 4;
    return { ...step, key, phase, index: idx };
  });
}

function buildEmptySlots(steps) {
  const slots = {};
  steps.forEach(step => {
    slots[step.key] = { alternates: [] };
  });
  return slots;
}

// Exact 4 Bands with paired two-column rows (Blue left, Red right)
const DRAFT_BANDS = [
  {
    id: 'band1',
    bg: 'rgba(242, 167, 195, 0.22)',
    border: '1.5px solid rgba(242, 167, 195, 0.55)',
    rows: [
      { left: 'BB1', right: 'RB1' },
      { left: 'BB2', right: 'RB2' },
      { left: 'BB3', right: 'RB3' },
    ],
  },
  {
    id: 'band2',
    bg: 'rgba(124, 191, 142, 0.22)',
    border: '1.5px solid rgba(124, 191, 142, 0.55)',
    rows: [
      { left: 'B1', right: 'R1' },
      { left: 'B2', right: 'R2' },
      { left: 'B3', right: 'R3' },
    ],
  },
  {
    id: 'band3',
    bg: 'rgba(242, 167, 195, 0.22)',
    border: '1.5px solid rgba(242, 167, 195, 0.55)',
    rows: [
      { left: 'BB4', right: 'RB4' },
      { left: 'BB5', right: 'RB5' },
    ],
  },
  {
    id: 'band4',
    bg: 'rgba(124, 191, 142, 0.22)',
    border: '1.5px solid rgba(124, 191, 142, 0.55)',
    rows: [
      { left: 'B4', right: 'R4' },
      { left: 'B5', right: 'R5' },
    ],
  },
];

function SlotCell({
  scenarioId,
  slotKey,
  isLeft,
  alternates,
  onRemoveAlternate,
  onOpenPicker,
  onPointerDownItem,
  dragState,
  keyboardMoveSource,
  onSelectMoveTarget,
  onKeyboardReorder,
  prefersReducedMotion,
}) {
  const plusButton = (
    <div
      onClick={() => onOpenPicker && onOpenPicker(slotKey, alternates)}
      title={`Add alternate to ${slotKey}`}
      className="cozy-btn"
      style={{
        width: 26,
        height: 26,
        borderRadius: 6,
        border: '1.5px dashed var(--border-emphasis)',
        background: 'var(--surface-card)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        userSelect: 'none',
        flexShrink: 0,
        boxShadow: '0 1px 2px rgba(0,0,0,0.05)',
        cursor: 'pointer',
      }}
    >
      <span style={{ fontSize: 13, fontWeight: 900, color: 'var(--accent-orange)', lineHeight: 1 }}>
        +
      </span>
    </div>
  );

  const labelSpan = (
    <span
      style={{
        fontSize: 11,
        fontFamily: 'Nunito',
        fontWeight: 800,
        color: 'var(--text-muted)',
        userSelect: 'none',
        flexShrink: 0,
      }}
    >
      {slotKey}
    </span>
  );

  const items = (alternates || []).map((champId, idx) => ({
    champId,
    idx,
    isPrimary: idx === 0,
  }));

  const displayList = isLeft ? [...items].reverse() : items;

  const renderedAlternates = displayList.map(({ champId, idx, isPrimary }) => {
    const size = isPrimary ? 40 : 30;
    const radius = isPrimary ? 10 : 7;

    const isThisBeingDragged = dragState?.source?.slotKey === slotKey && dragState?.source?.idx === idx;
    const isDropTarget = dragState?.dropTarget?.slotKey === slotKey && dragState?.dropTarget?.idx === idx;
    const isKeyboardSource = keyboardMoveSource?.slotKey === slotKey && keyboardMoveSource?.idx === idx;

    let borderStyle = isPrimary ? '2.5px solid var(--accent-orange)' : '1.5px solid var(--border-default)';
    let boxShadowStyle = isPrimary
      ? '0 0 0 2px var(--surface-card), 0 0 0 4px var(--accent-orange)'
      : 'none';
    let transformStyle = 'none';

    if (isThisBeingDragged) {
      borderStyle = '2px dashed var(--accent-orange)';
      boxShadowStyle = 'none';
    } else if (isDropTarget) {
      borderStyle = '2.5px solid var(--accent-green)';
      boxShadowStyle = '0 0 0 3px var(--accent-green), 0 0 10px rgba(124, 191, 142, 0.6)';
      if (!prefersReducedMotion) transformStyle = 'scale(1.18)';
    } else if (isKeyboardSource) {
      borderStyle = '2.5px solid var(--accent-orange)';
      boxShadowStyle = '0 0 0 3px var(--accent-orange)';
      if (!prefersReducedMotion) transformStyle = 'scale(1.08)';
    }

    return (
      <div
        key={`${champId}-${idx}`}
        data-drag-target="true"
        data-scenario-id={scenarioId}
        data-slot-key={slotKey}
        data-slot-idx={idx}
        data-champ-id={champId}
        tabIndex={0}
        role="button"
        aria-label={`${champId}, ${isPrimary ? 'primary pick' : `fallback #${idx}`} in ${slotKey}. Press Arrow keys to reorder in slot, M to move, or click to swap.`}
        onPointerDown={(e) => {
          const targetElem = e.target instanceof Element ? e.target : e.target?.parentElement;
          if (targetElem?.closest?.('[data-delete-btn="true"], [data-action="delete-alternate"], .delete-alternate-btn')) {
            return;
          }
          onPointerDownItem && onPointerDownItem(e, { slotKey, idx, champId });
        }}
        onClick={(e) => {
          const targetElem = e.target instanceof Element ? e.target : e.target?.parentElement;
          if (targetElem?.closest?.('[data-delete-btn="true"], [data-action="delete-alternate"], .delete-alternate-btn')) {
            return;
          }
          if (keyboardMoveSource) {
            e.stopPropagation();
            onSelectMoveTarget && onSelectMoveTarget({ slotKey, idx, champId });
            return;
          }
          onOpenPicker && onOpenPicker(slotKey, alternates, idx);
        }}
        onKeyDown={(e) => {
          if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
            e.preventDefault();
            if (idx > 0) {
              onKeyboardReorder && onKeyboardReorder(
                { slotKey, idx, champId },
                { slotKey, idx: idx - 1, champId: alternates[idx - 1] }
              );
            }
          } else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
            e.preventDefault();
            if (idx < (alternates || []).length - 1) {
              onKeyboardReorder && onKeyboardReorder(
                { slotKey, idx, champId },
                { slotKey, idx: idx + 1, champId: alternates[idx + 1] }
              );
            }
          } else if (e.key === 'm' || e.key === 'M') {
            e.preventDefault();
            if (isKeyboardSource) {
              onSelectMoveTarget && onSelectMoveTarget(null);
            } else {
              onSelectMoveTarget && onSelectMoveTarget({ slotKey, idx, champId }, true);
            }
          } else if (e.key === 'Enter' || e.key === ' ') {
            if (keyboardMoveSource) {
              e.preventDefault();
              onSelectMoveTarget && onSelectMoveTarget({ slotKey, idx, champId });
            }
          } else if (e.key === 'Escape') {
            if (keyboardMoveSource) {
              e.preventDefault();
              onSelectMoveTarget && onSelectMoveTarget(null);
            }
          }
        }}
        title={`${champId} (${isPrimary ? 'Primary' : `Fallback #${idx}`}) · Drag to reorder, press M to move, or click to swap`}
        className="champion-sticker"
        style={{
          position: 'relative',
          width: size,
          height: size,
          borderRadius: radius,
          flexShrink: 0,
          border: borderStyle,
          boxShadow: boxShadowStyle,
          transform: transformStyle,
          boxSizing: 'border-box',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          cursor: isThisBeingDragged ? 'grabbing' : 'grab',
          opacity: isThisBeingDragged ? 0.3 : (isPrimary ? 1 : 0.72),
          touchAction: 'none',
          userSelect: 'none',
          zIndex: isDropTarget ? 10 : 1,
          transition: prefersReducedMotion ? 'none' : 'all 0.18s cubic-bezier(0.34, 1.56, 0.64, 1)',
        }}
      >
        {window.ChampionIcon ? (
          <window.ChampionIcon
            championId={champId}
            size={isPrimary ? 34 : 24}
            noAnim
            style={{
              border: 'none',
              borderRadius: isPrimary ? 7 : 5,
              width: '100%',
              height: '100%',
            }}
          />
        ) : (
          <div style={{
            width: '100%', height: '100%', borderRadius: isPrimary ? 7 : 5, background: 'var(--surface-nested)',
            display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: isPrimary ? 13 : 10, fontWeight: 800,
          }}>
            {champId ? champId.slice(0, 2) : '?'}
          </div>
        )}
        {onRemoveAlternate && (
          <button
            type="button"
            data-delete-btn="true"
            data-action="delete-alternate"
            className="delete-alternate-btn"
            onPointerDown={(e) => {
              e.stopPropagation();
            }}
            onClick={(e) => {
              e.stopPropagation();
              onRemoveAlternate(slotKey, champId);
            }}
            title={`Remove ${champId}`}
            aria-label={`Remove ${champId} from ${slotKey}`}
            style={{
              position: 'absolute',
              top: -22,
              right: -22,
              width: 44,
              height: 44,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              background: 'transparent',
              border: 'none',
              padding: 0,
              cursor: 'pointer',
              zIndex: 15,
              pointerEvents: dragState ? 'none' : 'auto',
              touchAction: 'manipulation',
              userSelect: 'none',
            }}
          >
            <span
              style={{
                width: isPrimary ? 16 : 14,
                height: isPrimary ? 16 : 14,
                borderRadius: '50%',
                background: '#E85555',
                color: '#fff',
                border: '1.5px solid #fff',
                boxShadow: '0 1px 3px rgba(0,0,0,0.35)',
                fontSize: isPrimary ? 10 : 9,
                fontWeight: 900,
                lineHeight: 1,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                pointerEvents: 'none',
              }}
            >
              ×
            </span>
          </button>
        )}
      </div>
    );
  });

  const emptyIdx = (alternates || []).length;
  const isDraggingAny = Boolean(dragState);
  const isDropTargetEmpty = dragState?.dropTarget?.slotKey === slotKey && dragState?.dropTarget?.idx === emptyIdx;
  const isKeyboardSourceInOther = Boolean(keyboardMoveSource && (keyboardMoveSource.slotKey !== slotKey || keyboardMoveSource.idx !== emptyIdx));
  const isDragFromOther = Boolean(dragState && (dragState.source.slotKey !== slotKey || dragState.source.idx !== emptyIdx));
  const showEmptyTarget = (alternates || []).length === 0 || isDragFromOther || isKeyboardSourceInOther;

  const emptyTarget = showEmptyTarget ? (
    <div
      key={`empty-${slotKey}-${emptyIdx}`}
      data-drag-target="true"
      data-scenario-id={scenarioId}
      data-slot-key={slotKey}
      data-slot-idx={emptyIdx}
      data-champ-id=""
      role="button"
      tabIndex={keyboardMoveSource ? 0 : -1}
      aria-label={`Empty target position in ${slotKey}`}
      onClick={(e) => {
        if (keyboardMoveSource) {
          e.stopPropagation();
          onSelectMoveTarget && onSelectMoveTarget({ slotKey, idx: emptyIdx, champId: null });
        }
      }}
      onKeyDown={(e) => {
        if (keyboardMoveSource && (e.key === 'Enter' || e.key === ' ')) {
          e.preventDefault();
          e.stopPropagation();
          onSelectMoveTarget && onSelectMoveTarget({ slotKey, idx: emptyIdx, champId: null });
        } else if (e.key === 'Escape') {
          onSelectMoveTarget && onSelectMoveTarget(null);
        }
      }}
      style={{
        width: (alternates || []).length === 0 ? 34 : 26,
        height: (alternates || []).length === 0 ? 34 : 26,
        borderRadius: (alternates || []).length === 0 ? 9 : 7,
        border: isDropTargetEmpty
          ? '2px dashed var(--accent-green)'
          : (isDraggingAny || keyboardMoveSource ? '1.5px dashed var(--border-emphasis)' : '1px dashed var(--border-default)'),
        background: isDropTargetEmpty ? 'rgba(124, 191, 142, 0.25)' : 'transparent',
        boxShadow: isDropTargetEmpty ? '0 0 8px rgba(124, 191, 142, 0.5)' : 'none',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: 11,
        color: isDropTargetEmpty ? 'var(--accent-green)' : 'var(--text-muted)',
        cursor: (isDraggingAny || keyboardMoveSource) ? 'pointer' : 'default',
        flexShrink: 0,
        boxSizing: 'border-box',
        transition: prefersReducedMotion ? 'none' : 'all 0.15s ease',
        transform: (isDropTargetEmpty && !prefersReducedMotion) ? 'scale(1.15)' : 'none',
      }}
      title={(alternates || []).length === 0 ? `Empty ${slotKey} (drop champion here)` : `Move to end of ${slotKey}`}
    >
      {isDropTargetEmpty ? '📥' : ((alternates || []).length === 0 ? '·' : '+')}
    </div>
  ) : null;

  if (isLeft) {
    // Left-side cell: [+ button] → [label text] → [fallback icons, highest index first] → [primary icon, index 0, closest to the center divider]
    return (
      <div
        style={{
          flex: 1,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          minHeight: 44,
          minWidth: 0,
          gap: 6,
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
          {plusButton}
          {labelSpan}
        </div>
        <div style={{
          display: 'flex',
          alignItems: 'center',
          columnGap: 14,
          rowGap: 6,
          minWidth: 0,
          justifyContent: 'flex-end',
          flexWrap: 'wrap',
        }}>
          {emptyTarget}
          {renderedAlternates}
        </div>
      </div>
    );
  }

  // Right-side cell: [primary icon, index 0, closest to the center divider] → [fallback icons, increasing index outward] → [label text] → [+ button]
  return (
    <div
      style={{
        flex: 1,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'space-between',
        minHeight: 44,
        minWidth: 0,
        gap: 6,
      }}
    >
      <div style={{
        display: 'flex',
        alignItems: 'center',
        columnGap: 14,
        rowGap: 6,
        minWidth: 0,
        justifyContent: 'flex-start',
        flexWrap: 'wrap',
      }}>
        {renderedAlternates}
        {emptyTarget}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
        {labelSpan}
        {plusButton}
      </div>
    </div>
  );
}

function DraftLabScenarioCard({
  scenario,
  lobbyCode,
  isSelected,
  isDraggingThis,
  onDragStart,
  onDragEnd,
  onCardDragOver,
  onDrop,
  onCardClick,
  onDuplicate,
  onDelete,
  onRemoveAlternate,
  onOpenPicker,
}) {
  const debouncedNotes = window.useDebounceFirebaseUpdate(
    scenario?.notes || '',
    (val) => {
      if (!lobbyCode || !window.db || !scenario?.id) return;
      window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios/${scenario.id}/notes`).set(val || '');
    },
    800
  );

  const prefersReducedMotion = typeof window !== 'undefined' &&
    window.matchMedia &&
    window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  const [dragState, setDragState] = useState(null);
  const [keyboardMoveSource, setKeyboardMoveSource] = useState(null);

  // Scenario title rename state
  const [isEditingTitle, setIsEditingTitle] = useState(false);
  const [titleDraft, setTitleDraft] = useState(scenario?.title || 'Untitled Scenario');

  useEffect(() => {
    if (!isEditingTitle) {
      setTitleDraft(scenario?.title || 'Untitled Scenario');
    }
  }, [scenario?.title, isEditingTitle]);

  const handleStartRename = useCallback((e) => {
    e?.stopPropagation();
    setTitleDraft(scenario?.title || 'Untitled Scenario');
    setIsEditingTitle(true);
  }, [scenario?.title]);

  const handleCommitRename = useCallback(() => {
    if (!isEditingTitle) return;
    const currentTitle = scenario?.title || 'Untitled Scenario';
    const cleanTitle = titleDraft.trim();
    // Basic validation: don't allow saving empty name (revert to previous name)
    if (cleanTitle && cleanTitle !== currentTitle && lobbyCode && window.db && scenario?.id) {
      // Single leaf write to Firebase: writes ONLY the title field
      window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios/${scenario.id}/title`).set(cleanTitle);
    } else {
      setTitleDraft(currentTitle);
    }
    setIsEditingTitle(false);
  }, [isEditingTitle, titleDraft, scenario?.title, scenario?.id, lobbyCode]);

  const handleCancelRename = useCallback(() => {
    setTitleDraft(scenario?.title || 'Untitled Scenario');
    setIsEditingTitle(false);
  }, [scenario?.title]);

  const pointerDownInfo = useRef(null);
  const justDraggedRef = useRef(false);

  // Multi-path atomic Firebase update: at most 2 leaf writes!
  const handleSwapOrMove = useCallback((source, target) => {
    if (!lobbyCode || !window.db || !scenario?.id || !source || !target) return;
    const { slotKey: srcSlot, idx: srcIdx, champId: srcChamp } = source;
    const { slotKey: targetSlot, idx: targetIdx, champId: targetChamp } = target;

    // Dropping back on its own original position is a no-op
    if (srcSlot === targetSlot && srcIdx === targetIdx) return;

    const updates = {};
    const basePath = `rooms/${lobbyCode}/draftLab/scenarios/${scenario.id}`;

    if (targetChamp) {
      // Target position already holds a champion: swap the two champions' positions
      updates[`slots/${srcSlot}/alternates/${srcIdx}`] = targetChamp;
      updates[`slots/${targetSlot}/alternates/${targetIdx}`] = srcChamp;
    } else {
      // Target position is empty: remove from source position and place at target position
      updates[`slots/${targetSlot}/alternates/${targetIdx}`] = srcChamp;
      updates[`slots/${srcSlot}/alternates/${srcIdx}`] = null;
    }

    window.db.ref(basePath).update(updates);
  }, [lobbyCode, scenario?.id]);

  const handleSelectMoveTarget = useCallback((target, isStartingMove = false) => {
    if (isStartingMove) {
      setKeyboardMoveSource(target);
      return;
    }
    if (!target) {
      setKeyboardMoveSource(null);
      return;
    }
    if (keyboardMoveSource) {
      handleSwapOrMove(keyboardMoveSource, target);
      setKeyboardMoveSource(null);
    }
  }, [keyboardMoveSource, handleSwapOrMove]);

  const handlePointerDown = useCallback((e, source) => {
    if (e.button !== undefined && e.button !== 0) return;
    const targetElem = e.target instanceof Element ? e.target : e.target?.parentElement;
    if (targetElem?.closest?.('[data-delete-btn="true"], [data-action="delete-alternate"], .delete-alternate-btn, button')) {
      return;
    }

    pointerDownInfo.current = {
      startX: e.clientX,
      startY: e.clientY,
      source,
      active: false,
    };

    const handlePointerMove = (moveEvent) => {
      if (!pointerDownInfo.current) return;
      const { startX, startY, source: dragSource, active } = pointerDownInfo.current;
      const dist = Math.hypot(moveEvent.clientX - startX, moveEvent.clientY - startY);

      if (!active && dist > 5) {
        pointerDownInfo.current.active = true;
        justDraggedRef.current = true;
      }

      if (pointerDownInfo.current.active) {
        const elem = document.elementFromPoint(moveEvent.clientX, moveEvent.clientY);
        const targetElem = elem ? elem.closest(`[data-scenario-id="${scenario.id}"][data-drag-target="true"]`) : null;
        let dropTarget = null;
        if (targetElem) {
          dropTarget = {
            slotKey: targetElem.getAttribute('data-slot-key'),
            idx: Number(targetElem.getAttribute('data-slot-idx')),
            champId: targetElem.getAttribute('data-champ-id') || null,
          };
        }

        setDragState({
          source: dragSource,
          currentPos: { x: moveEvent.clientX, y: moveEvent.clientY },
          dropTarget,
        });
      }
    };

    const handlePointerUp = (upEvent) => {
      window.removeEventListener('pointermove', handlePointerMove);
      window.removeEventListener('pointerup', handlePointerUp);
      window.removeEventListener('pointercancel', handlePointerUp);

      if (pointerDownInfo.current?.active) {
        const elem = document.elementFromPoint(upEvent.clientX, upEvent.clientY);
        const targetElem = elem ? elem.closest(`[data-scenario-id="${scenario.id}"][data-drag-target="true"]`) : null;
        if (targetElem) {
          const finalDropTarget = {
            slotKey: targetElem.getAttribute('data-slot-key'),
            idx: Number(targetElem.getAttribute('data-slot-idx')),
            champId: targetElem.getAttribute('data-champ-id') || null,
          };
          handleSwapOrMove(pointerDownInfo.current.source, finalDropTarget);
        }
        setTimeout(() => {
          justDraggedRef.current = false;
        }, 80);
      } else {
        justDraggedRef.current = false;
      }

      pointerDownInfo.current = null;
      setDragState(null);
    };

    window.addEventListener('pointermove', handlePointerMove);
    window.addEventListener('pointerup', handlePointerUp);
    window.addEventListener('pointercancel', handlePointerUp);
  }, [scenario?.id, handleSwapOrMove]);

  return (
    <div
      className="secondary-card"
      draggable={true}
      onDragStart={(e) => {
        // If clicking on an interactive button, input, or champion sticker, don't trigger drag
        if (e.target.closest('button, input, .champion-sticker, .cozy-btn')) {
          e.preventDefault();
          return;
        }
        e.dataTransfer.setData('text/plain', scenario.id);
        e.dataTransfer.effectAllowed = 'move';
        onDragStart && onDragStart(scenario);
      }}
      onDragEnd={() => {
        onDragEnd && onDragEnd();
      }}
      onDragOver={(e) => {
        e.preventDefault();
        e.stopPropagation();
        onCardDragOver && onCardDragOver(scenario, e);
      }}
      onDrop={(e) => {
        e.preventDefault();
        e.stopPropagation();
        onDrop && onDrop();
      }}
      onClick={(e) => {
        // If clicking on an interactive button, input, or champion sticker, don't trigger selection
        if (e.target.closest('button, input, .champion-sticker, .cozy-btn')) {
          return;
        }
        onCardClick && onCardClick(scenario, e);
      }}
      style={{
        flex: '0 0 350px',
        width: 350,
        background: isSelected ? 'rgba(196, 132, 90, 0.09)' : 'var(--surface-card)',
        border: isSelected ? '2.5px solid var(--accent-orange)' : '2px solid var(--border-default)',
        borderRadius: 18,
        padding: 16,
        display: 'flex',
        flexDirection: 'column',
        gap: 10,
        boxShadow: isSelected
          ? '0 0 0 2px rgba(196, 132, 90, 0.4), 0 6px 16px rgba(196, 132, 90, 0.15)'
          : '0 3px 0 var(--border-default)',
        transition: 'all 0.18s cubic-bezier(0.34, 1.56, 0.64, 1)',
        cursor: isDraggingThis ? 'grabbing' : 'grab',
        opacity: isDraggingThis ? 0.38 : 1,
        transform: isDraggingThis ? 'scale(0.98)' : 'none',
      }}
    >
      {/* Header: Drag Grip + Title + Duplicate / Delete buttons */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0, flex: 1 }}>
          <span
            title="Drag to reorder"
            style={{
              cursor: isDraggingThis ? 'grabbing' : 'grab',
              color: 'var(--text-muted)',
              opacity: 0.7,
              fontSize: 15,
              fontWeight: 900,
              userSelect: 'none',
              lineHeight: 1,
              flexShrink: 0,
              letterSpacing: -1,
            }}
          >
            ⋮⋮
          </span>
          {isEditingTitle ? (
            <input
              type="text"
              autoFocus
              value={titleDraft}
              onChange={e => setTitleDraft(e.target.value)}
              onFocus={e => e.target.select()}
              onBlur={handleCommitRename}
              onClick={e => e.stopPropagation()}
              onPointerDown={e => e.stopPropagation()}
              onKeyDown={e => {
                if (e.key === 'Enter') {
                  e.preventDefault();
                  handleCommitRename();
                } else if (e.key === 'Escape') {
                  e.preventDefault();
                  handleCancelRename();
                }
              }}
              style={{
                fontFamily: 'Fredoka, sans-serif',
                fontSize: 15,
                fontWeight: 600,
                color: 'var(--text-primary)',
                background: 'var(--surface-nested)',
                border: '1.5px solid var(--accent-orange)',
                borderRadius: 8,
                padding: '2px 8px',
                outline: 'none',
                width: '100%',
                minWidth: 120,
                maxWidth: 210,
                boxSizing: 'border-box',
              }}
              aria-label="Rename scenario"
            />
          ) : (
            <div
              onClick={handleStartRename}
              title="Click to rename scenario"
              style={{
                display: 'flex',
                alignItems: 'center',
                gap: 5,
                minWidth: 0,
                cursor: 'pointer',
                borderRadius: 6,
                padding: '2px 4px',
                margin: '-2px -4px',
                borderBottom: '1.5px dashed transparent',
                transition: 'border-color 0.15s, background 0.15s',
              }}
              onMouseEnter={e => {
                e.currentTarget.style.borderBottomColor = 'var(--accent-orange)';
              }}
              onMouseLeave={e => {
                e.currentTarget.style.borderBottomColor = 'transparent';
              }}
            >
              <h4
                className="fredoka"
                style={{
                  fontSize: 16,
                  color: 'var(--text-primary)',
                  margin: 0,
                  overflow: 'hidden',
                  textOverflow: 'ellipsis',
                  whiteSpace: 'nowrap',
                }}
              >
                {scenario?.title || 'Untitled Scenario'}
              </h4>
              <span
                style={{
                  fontSize: 12,
                  color: 'var(--text-muted)',
                  opacity: 0.65,
                  userSelect: 'none',
                  flexShrink: 0,
                }}
                aria-label="Rename scenario"
              >
                ✏️
              </span>
            </div>
          )}
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <button
            onClick={() => onDuplicate(scenario)}
            title="Duplicate scenario"
            className="cozy-btn"
            style={{
              background: 'var(--surface-nested)',
              border: '1.5px solid var(--border-default)',
              borderRadius: 8,
              padding: '5px 8px',
              cursor: 'pointer',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <LabDuplicateIcon size={15} color="var(--text-muted)" />
          </button>

          <button
            onClick={() => onDelete(scenario)}
            title="Delete scenario"
            className="cozy-btn"
            style={{
              background: 'var(--surface-nested)',
              border: '1.5px solid rgba(232, 85, 85, 0.35)',
              borderRadius: 8,
              padding: '5px 8px',
              cursor: 'pointer',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
            }}
          >
            <LabTrashIcon size={15} color="#E85555" />
          </button>
        </div>
      </div>

      {/* Keyboard/Accessibility Move Mode banner */}
      {keyboardMoveSource && (
        <div
          role="status"
          aria-live="polite"
          style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
            background: 'rgba(196, 132, 90, 0.16)',
            border: '1.5px solid var(--accent-orange)',
            borderRadius: 10,
            padding: '5px 10px',
            fontSize: 11,
            fontFamily: 'Nunito',
            fontWeight: 800,
            color: 'var(--accent-orange)',
            animation: prefersReducedMotion ? 'none' : 'float 2s ease-in-out infinite',
          }}
        >
          <span>
            Moving <strong>{keyboardMoveSource.champId}</strong> ({keyboardMoveSource.slotKey}) — select target (Enter/Space) or Esc
          </span>
          <button
            onClick={() => setKeyboardMoveSource(null)}
            style={{
              background: 'transparent',
              border: 'none',
              color: 'var(--accent-orange)',
              fontWeight: 900,
              cursor: 'pointer',
              fontSize: 12,
              padding: '0 4px',
            }}
            title="Cancel move"
            aria-label="Cancel move"
          >
            ✕
          </button>
        </div>
      )}

      {/* 20 slots laid out in four colored bands with paired rows */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        {DRAFT_BANDS.map(band => (
          <div
            key={band.id}
            style={{
              background: band.bg,
              border: band.border,
              borderRadius: 10,
              padding: '4px 8px',
              display: 'flex',
              flexDirection: 'column',
              gap: 4,
            }}
          >
            {band.rows.map(row => (
              <div
                key={`${row.left}-${row.right}`}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: 8,
                  padding: '2px 0',
                }}
              >
                <SlotCell
                  scenarioId={scenario.id}
                  slotKey={row.left}
                  isLeft={true}
                  alternates={scenario?.slots?.[row.left]?.alternates ?? []}
                  onRemoveAlternate={(slotKey, champId) => onRemoveAlternate(slotKey, champId)}
                  onOpenPicker={(slotKey, alts, swapIdx) => onOpenPicker && onOpenPicker(scenario.id, slotKey, alts, swapIdx)}
                  onPointerDownItem={handlePointerDown}
                  dragState={dragState}
                  keyboardMoveSource={keyboardMoveSource}
                  onSelectMoveTarget={handleSelectMoveTarget}
                  onKeyboardReorder={handleSwapOrMove}
                  prefersReducedMotion={prefersReducedMotion}
                />
                <div style={{
                  width: 1,
                  height: 18,
                  background: 'var(--border-default)',
                  opacity: 0.35,
                  flexShrink: 0,
                }} />
                <SlotCell
                  scenarioId={scenario.id}
                  slotKey={row.right}
                  isLeft={false}
                  alternates={scenario?.slots?.[row.right]?.alternates ?? []}
                  onRemoveAlternate={(slotKey, champId) => onRemoveAlternate(slotKey, champId)}
                  onOpenPicker={(slotKey, alts, swapIdx) => onOpenPicker && onOpenPicker(scenario.id, slotKey, alts, swapIdx)}
                  onPointerDownItem={handlePointerDown}
                  dragState={dragState}
                  keyboardMoveSource={keyboardMoveSource}
                  onSelectMoveTarget={handleSelectMoveTarget}
                  onKeyboardReorder={handleSwapOrMove}
                  prefersReducedMotion={prefersReducedMotion}
                />
              </div>
            ))}
          </div>
        ))}
      </div>

      {/* Floating Drag Avatar Ghost */}
      {dragState && (
        <div
          style={{
            position: 'fixed',
            left: dragState.currentPos.x - 20,
            top: dragState.currentPos.y - 20,
            width: 40,
            height: 40,
            borderRadius: 10,
            pointerEvents: 'none',
            zIndex: 99999,
            border: '2.5px solid var(--accent-orange)',
            boxShadow: '0 8px 20px rgba(0,0,0,0.35)',
            transform: prefersReducedMotion ? 'none' : 'scale(1.15) rotate(3deg)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            background: 'var(--surface-card)',
            boxSizing: 'border-box',
          }}
        >
          {window.ChampionIcon ? (
            <window.ChampionIcon
              championId={dragState.source.champId}
              size={34}
              noAnim
              style={{ border: 'none', borderRadius: 7, width: '100%', height: '100%' }}
            />
          ) : (
            <span style={{ fontSize: 13, fontWeight: 800 }}>{dragState.source.champId?.slice(0, 2)}</span>
          )}
        </div>
      )}

      {/* Notes text input at the bottom with debounced writes */}
      <div style={{ marginTop: 'auto', paddingTop: 2 }}>
        <input
          type="text"
          value={debouncedNotes.value || ''}
          onChange={e => debouncedNotes.onChange(e.target.value)}
          onBlur={debouncedNotes.onBlur}
          onFocus={debouncedNotes.onFocus}
          placeholder="Notes..."
          style={{
            width: '100%',
            padding: '7px 12px',
            borderRadius: 10,
            border: '1.5px solid var(--border-default)',
            background: 'var(--surface-nested)',
            color: 'var(--text-primary)',
            fontFamily: 'Nunito',
            fontSize: 12,
            fontWeight: 700,
            outline: 'none',
            boxSizing: 'border-box',
          }}
        />
      </div>
    </div>
  );
}

// Drop indicator placeholder between or after cards
function DropIndicatorPlaceholder() {
  return (
    <div
      style={{
        flex: '0 0 160px',
        width: 160,
        minHeight: 380,
        border: '2.5px dashed var(--accent-orange)',
        borderRadius: 18,
        background: 'rgba(196, 132, 90, 0.12)',
        boxShadow: '0 0 0 3px rgba(196, 132, 90, 0.2)',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
        pointerEvents: 'none',
        userSelect: 'none',
        transition: 'all 0.18s ease-in-out',
        flexShrink: 0,
        boxSizing: 'border-box',
      }}
    >
      <div style={{
        width: 38,
        height: 38,
        borderRadius: '50%',
        background: 'var(--accent-orange)',
        color: '#fff',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: 18,
        fontWeight: 900,
        boxShadow: '0 2px 6px rgba(196, 132, 90, 0.35)',
      }}>
        ↓
      </div>
      <span className="fredoka" style={{ fontSize: 14, color: 'var(--accent-orange)' }}>
        Drop here
      </span>
    </div>
  );
}

// Group Component: renders editable header with controls + horizontal cards row
function DraftLabGroup({
  group,
  scenarios,
  lobbyCode,
  selectedScenarioIds,
  draggedScenarioId,
  dropTarget,
  onDragStart,
  onDragEnd,
  onCardDragOver,
  onContainerDragOver,
  onDrop,
  onSelectAll,
  onAddSelected,
  onUngroup,
  onDuplicate,
  onDelete,
  onRemoveAlternate,
  onOpenPicker,
  onCardClick,
}) {
  const [isEditingName, setIsEditingName] = useState(false);
  const debouncedGroupName = window.useDebounceFirebaseUpdate(
    group.name || '',
    (val) => {
      if (!lobbyCode || !window.db || !group?.id) return;
      window.db.ref(`rooms/${lobbyCode}/draftLab/groups/${group.id}/name`).set(val || 'Untitled Group');
    },
    800
  );

  const groupScenarios = useMemo(() => {
    return scenarios
      .filter(s => s.groupId === group.id)
      .sort((a, b) => (a.order || 0) - (b.order || 0));
  }, [scenarios, group.id]);

  const count = groupScenarios.length;
  const isDragging = Boolean(draggedScenarioId);
  const isTargetGroup = isDragging && dropTarget?.targetGroupId === group.id;

  return (
    <div
      style={{
        background: 'var(--surface-card)',
        border: isTargetGroup ? '2px solid var(--accent-orange)' : '2px solid var(--border-emphasis)',
        borderRadius: 20,
        padding: 16,
        marginBottom: 24,
        boxShadow: isTargetGroup ? '0 4px 12px rgba(196, 132, 90, 0.25)' : '0 4px 0 var(--border-default)',
        transition: 'border-color 0.18s, box-shadow 0.18s',
      }}
    >
      {/* Group Header */}
      <div
        className="draftlab-group-header"
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          marginBottom: 14,
          paddingBottom: 10,
          borderBottom: '1.5px dashed var(--border-default)',
          flexWrap: 'wrap',
          gap: 12,
        }}
      >
        {/* Left side: Folder Icon + Editable Name */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, minWidth: 200, flex: '1 1 auto' }}>
          <span style={{ fontSize: 20 }}>📁</span>
          {isEditingName ? (
            <input
              type="text"
              autoFocus
              value={debouncedGroupName.value}
              onChange={e => debouncedGroupName.onChange(e.target.value)}
              onFocus={debouncedGroupName.onFocus}
              onBlur={(e) => {
                debouncedGroupName.onBlur(e);
                setIsEditingName(false);
              }}
              onKeyDown={(e) => {
                if (e.key === 'Enter') {
                  e.currentTarget.blur();
                }
              }}
              style={{
                fontFamily: 'Fredoka, sans-serif',
                fontSize: 20,
                fontWeight: 600,
                color: 'var(--accent-orange)',
                background: 'var(--surface-nested)',
                border: '1.5px solid var(--accent-orange)',
                borderRadius: 8,
                padding: '2px 8px',
                outline: 'none',
                maxWidth: 280,
              }}
            />
          ) : (
            <h3
              className="fredoka"
              onClick={() => setIsEditingName(true)}
              title="Click to rename group"
              style={{
                fontSize: 20,
                color: 'var(--accent-orange)',
                margin: 0,
                cursor: 'pointer',
                display: 'inline-flex',
                alignItems: 'center',
                gap: 6,
                borderBottom: '1.5px dashed transparent',
                transition: 'border-color 0.15s',
              }}
              onMouseEnter={e => e.currentTarget.style.borderBottomColor = 'var(--accent-orange)'}
              onMouseLeave={e => e.currentTarget.style.borderBottomColor = 'transparent'}
            >
              {group.name || 'Untitled Group'}
              <span style={{ fontSize: 13, color: 'var(--text-muted)', fontWeight: 400 }}>✏️</span>
            </h3>
          )}
        </div>

        {/* Right side: Controls matching reference: "{n} scenarios" · "Select all" · "+Add" · "Ungroup" */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
          {/* "{n} scenarios" */}
          <span
            style={{
              background: 'var(--surface-nested)',
              border: '1.5px solid var(--border-default)',
              borderRadius: 14,
              padding: '3px 10px',
              fontSize: 12,
              fontWeight: 800,
              color: 'var(--text-muted)',
              fontFamily: 'Nunito',
            }}
          >
            {count} {count === 1 ? 'scenario' : 'scenarios'}
          </span>

          <span style={{ color: 'var(--border-default)', fontWeight: 700 }}>·</span>

          {/* "Select all" button */}
          <button
            onClick={() => onSelectAll(group.id)}
            className="cozy-btn"
            style={{
              background: 'var(--surface-nested)',
              border: '1.5px solid var(--border-default)',
              borderRadius: 10,
              padding: '4px 10px',
              fontSize: 12,
              fontWeight: 800,
              fontFamily: 'Nunito',
              color: 'var(--text-primary)',
              cursor: 'pointer',
            }}
          >
            Select all
          </button>

          <span style={{ color: 'var(--border-default)', fontWeight: 700 }}>·</span>

          {/* "+Add" button */}
          <button
            onClick={() => onAddSelected(group.id)}
            title="Move selected scenarios into this group"
            className="cozy-btn"
            style={{
              background: 'rgba(196, 132, 90, 0.12)',
              border: '1.5px solid var(--accent-orange)',
              borderRadius: 10,
              padding: '4px 10px',
              fontSize: 12,
              fontWeight: 800,
              fontFamily: 'Nunito',
              color: 'var(--accent-orange)',
              cursor: 'pointer',
            }}
          >
            + Add
          </button>

          <span style={{ color: 'var(--border-default)', fontWeight: 700 }}>·</span>

          {/* "Ungroup" button */}
          <button
            onClick={() => onUngroup(group.id)}
            title="Move scenarios back to loose list and remove group"
            className="cozy-btn"
            style={{
              background: 'var(--surface-nested)',
              border: '1.5px solid rgba(232, 85, 85, 0.35)',
              borderRadius: 10,
              padding: '4px 10px',
              fontSize: 12,
              fontWeight: 800,
              fontFamily: 'Nunito',
              color: '#E85555',
              cursor: 'pointer',
            }}
          >
            Ungroup
          </button>
        </div>
      </div>

      {/* Scenarios Row inside Group */}
      <div
        onDragOver={(e) => {
          e.preventDefault();
          onContainerDragOver && onContainerDragOver(group.id, e);
        }}
        onDrop={(e) => {
          e.preventDefault();
          onDrop && onDrop(group.id);
        }}
        style={{
          display: 'flex',
          gap: 16,
          overflowX: 'auto',
          padding: '16px 14px 22px 14px',
          margin: '-8px -14px 0 -14px',
          alignItems: 'stretch',
          minHeight: 180,
        }}
      >
        {groupScenarios.map(scenario => {
          const showIndicatorBefore =
            isTargetGroup &&
            dropTarget?.beforeScenarioId === scenario.id &&
            draggedScenarioId !== scenario.id;

          return (
            <React.Fragment key={scenario.id}>
              {showIndicatorBefore && <DropIndicatorPlaceholder />}
              <DraftLabScenarioCard
                scenario={scenario}
                lobbyCode={lobbyCode}
                isSelected={selectedScenarioIds.includes(scenario.id)}
                isDraggingThis={draggedScenarioId === scenario.id}
                onDragStart={onDragStart}
                onDragEnd={onDragEnd}
                onCardDragOver={(sc, e) => onCardDragOver(sc, group.id, e)}
                onDrop={() => onDrop(group.id)}
                onCardClick={onCardClick}
                onDuplicate={onDuplicate}
                onDelete={onDelete}
                onRemoveAlternate={(slotKey, champId) => onRemoveAlternate(scenario.id, slotKey, champId)}
                onOpenPicker={onOpenPicker}
              />
            </React.Fragment>
          );
        })}

        {/* Drop indicator after last card in group */}
        {isTargetGroup &&
          dropTarget?.beforeScenarioId === null &&
          groupScenarios.length > 0 &&
          groupScenarios[groupScenarios.length - 1].id !== draggedScenarioId && (
            <DropIndicatorPlaceholder />
        )}

        {/* Empty group placeholder / drop zone */}
        {groupScenarios.length === 0 && (
          <div
            style={{
              flex: '0 0 280px',
              width: 280,
              minHeight: 180,
              border: isTargetGroup
                ? '2.5px dashed var(--accent-orange)'
                : '2px dashed var(--border-default)',
              borderRadius: 18,
              background: isTargetGroup
                ? 'rgba(196, 132, 90, 0.12)'
                : 'var(--surface-nested)',
              boxShadow: isTargetGroup
                ? '0 0 0 3px rgba(196, 132, 90, 0.2)'
                : 'none',
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center',
              justifyContent: 'center',
              gap: 8,
              padding: 20,
              transition: 'all 0.18s ease-in-out',
            }}
          >
            <span style={{ fontSize: 24 }}>{isTargetGroup ? '📥' : '📁'}</span>
            <span className="fredoka" style={{ fontSize: 14, color: 'var(--accent-orange)' }}>
              {isTargetGroup ? 'Drop scenario here' : 'Empty Group'}
            </span>
            <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textAlign: 'center' }}>
              {isTargetGroup ? 'Release to add scenario to this group' : 'Drag scenarios here or click “+Add” above 🌱'}
            </span>
          </div>
        )}
      </div>
    </div>
  );
}

function CreateScenarioCard({ onClick }) {
  return (
    <div
      onClick={onClick}
      className="cozy-btn"
      style={{
        flex: '0 0 220px',
        width: 220,
        minHeight: 380,
        background: 'rgba(196, 132, 90, 0.04)',
        border: '2.5px dashed var(--border-emphasis)',
        borderRadius: 18,
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 10,
        cursor: 'pointer',
        padding: 20,
        textAlign: 'center',
        userSelect: 'none',
      }}
    >
      <div style={{
        width: 46,
        height: 46,
        borderRadius: '50%',
        background: 'var(--surface-card)',
        border: '2px solid var(--border-emphasis)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: 24,
        fontWeight: 900,
        color: 'var(--accent-orange)',
        boxShadow: '0 2px 4px rgba(0,0,0,0.06)',
      }}>
        +
      </div>
      <span className="fredoka" style={{ fontSize: 16, color: 'var(--accent-orange)' }}>
        Create scenario
      </span>
      <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', lineHeight: 1.4 }}>
        Add a new draft scenario to test picks & bans
      </span>
    </div>
  );
}

function DraftLab() {
  const { lobbyCode, showToast, myUserId, sessionUserId } = useApp();
  const [scenarios, setScenarios] = useState([]);
  const [groups, setGroups] = useState([]);
  const [loading, setLoading] = useState(true);
  const [selectedScenarioIds, setSelectedScenarioIds] = useState([]);

  // Drag-and-drop state
  const [draggedScenarioId, setDraggedScenarioId] = useState(null);
  const [dropTarget, setDropTarget] = useState(null); // { targetGroupId: string|null, beforeScenarioId: string|null }

  const steps = useMemo(() => getDraftStepList(), []);

  // Live-sync with Firebase RTDB under rooms/{lobbyCode}/draftLab/
  useEffect(() => {
    if (!lobbyCode || !window.db) {
      setLoading(false);
      return;
    }

    const scenariosRef = window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios`);
    const groupsRef = window.db.ref(`rooms/${lobbyCode}/draftLab/groups`);

    const handleScenarios = (snap) => {
      const val = snap.val() || {};
      const list = Object.entries(val).map(([id, data]) => ({
        id,
        ...data,
      }));
      setScenarios(list);
      setLoading(false);
    };

    const handleGroups = (snap) => {
      const val = snap.val() || {};
      const list = Object.entries(val).map(([id, data]) => ({
        id,
        ...data,
      }));
      setGroups(list);
    };

    scenariosRef.on('value', handleScenarios);
    groupsRef.on('value', handleGroups);

    return () => {
      scenariosRef.off('value', handleScenarios);
      groupsRef.off('value', handleGroups);
    };
  }, [lobbyCode]);

  // Current user ID for createdBy
  const getCurrentUid = useCallback(() => {
    const authUser = window.firebase && window.firebase.auth ? window.firebase.auth().currentUser : null;
    return (authUser && authUser.uid) || myUserId || sessionUserId || 'anonymous';
  }, [myUserId, sessionUserId]);

  // Loose scenarios: groupId === null (or not set)
  const looseScenarios = useMemo(() => {
    return scenarios
      .filter(s => s.groupId === null || s.groupId === undefined)
      .sort((a, b) => (a.order || 0) - (b.order || 0));
  }, [scenarios]);

  // Groups sorted by order
  const sortedGroups = useMemo(() => {
    return [...groups].sort((a, b) => (a.order || 0) - (b.order || 0));
  }, [groups]);

  // Handler: Card selection logic
  // 1. Click: selects only that card (clears others)
  // 2. Ctrl-click / Cmd-click: toggles that card in/out of multi-select
  // 3. Shift-click: selects all scenarios in that card's group (or all loose scenarios if in loose list)
  const handleCardClick = useCallback((scenario, e) => {
    const isCtrlOrCmd = e.ctrlKey || e.metaKey;
    const isShift = e.shiftKey;

    if (isShift) {
      const targetGroupId = scenario.groupId || null;
      const allInSameGroup = scenarios
        .filter(s => (s.groupId || null) === targetGroupId)
        .map(s => s.id);
      setSelectedScenarioIds(allInSameGroup);
    } else if (isCtrlOrCmd) {
      setSelectedScenarioIds(prev =>
        prev.includes(scenario.id)
          ? prev.filter(id => id !== scenario.id)
          : [...prev, scenario.id]
      );
    } else {
      setSelectedScenarioIds([scenario.id]);
    }
  }, [scenarios]);

  // Handler: Clicking empty board space (not a card or control) clears selection
  const handleBoardClick = useCallback((e) => {
    if (e.target.closest('.secondary-card, button, input, .cozy-btn, .champion-sticker, .draftlab-group-header')) {
      return;
    }
    setSelectedScenarioIds([]);
  }, []);

  // ── Drag and Drop Handlers ──
  const handleDragStart = useCallback((scenario) => {
    setDraggedScenarioId(scenario.id);
  }, []);

  const handleDragEnd = useCallback(() => {
    setDraggedScenarioId(null);
    setDropTarget(null);
  }, []);

  const handleCardDragOver = useCallback((cardScenario, targetGroupId, e) => {
    e.preventDefault();
    e.stopPropagation();
    if (!draggedScenarioId || cardScenario.id === draggedScenarioId) return;

    const rect = e.currentTarget.getBoundingClientRect();
    const midX = rect.left + rect.width / 2;
    const isLeft = e.clientX < midX;

    const destCards = scenarios
      .filter(s => (s.groupId || null) === (targetGroupId || null) && s.id !== draggedScenarioId)
      .sort((a, b) => (a.order || 0) - (b.order || 0));

    let beforeId;
    if (isLeft) {
      beforeId = cardScenario.id;
    } else {
      const cardIdx = destCards.findIndex(s => s.id === cardScenario.id);
      if (cardIdx !== -1 && cardIdx + 1 < destCards.length) {
        beforeId = destCards[cardIdx + 1].id;
      } else {
        beforeId = null; // after the last card
      }
    }

    setDropTarget(prev => {
      if (prev && prev.targetGroupId === targetGroupId && prev.beforeScenarioId === beforeId) {
        return prev;
      }
      return {
        targetGroupId,
        beforeScenarioId: beforeId,
      };
    });
  }, [draggedScenarioId, scenarios]);

  const handleContainerDragOver = useCallback((targetGroupId, e) => {
    e.preventDefault();
    if (!draggedScenarioId) return;

    setDropTarget(prev => {
      if (prev && prev.targetGroupId === targetGroupId && prev.beforeScenarioId === null) {
        return prev;
      }
      return {
        targetGroupId,
        beforeScenarioId: null,
      };
    });
  }, [draggedScenarioId]);

  // Handler: Drop logic using fractional order values
  // - Between two existing cards with order A and B (A < B): (A + B) / 2
  // - Before the first card (order F): F - 1
  // - After the last card (order L): L + 1
  // - In empty group or empty loose list: 0
  // - Scoped single write to rooms/{lobbyCode}/draftLab/scenarios/{movedId} update { groupId, order }
  const handleDrop = useCallback(async (targetGroupId) => {
    if (!draggedScenarioId || !lobbyCode || !window.db) {
      setDraggedScenarioId(null);
      setDropTarget(null);
      return;
    }

    const movedScenario = scenarios.find(s => s.id === draggedScenarioId);
    if (!movedScenario) {
      setDraggedScenarioId(null);
      setDropTarget(null);
      return;
    }

    const currentDropTarget = dropTarget;
    setDraggedScenarioId(null);
    setDropTarget(null);

    const destCards = scenarios
      .filter(s => (s.groupId || null) === (targetGroupId || null) && s.id !== movedScenario.id)
      .sort((a, b) => (a.order || 0) - (b.order || 0));

    let newOrder;
    const M = destCards.length;

    if (M === 0) {
      newOrder = 0;
    } else if (!currentDropTarget || currentDropTarget.beforeScenarioId === null) {
      // Dropped after the last card
      const L = typeof destCards[M - 1].order === 'number' ? destCards[M - 1].order : 0;
      newOrder = L + 1;
    } else {
      const idx = destCards.findIndex(s => s.id === currentDropTarget.beforeScenarioId);
      if (idx <= 0) {
        // Dropped before the first card
        const F = typeof destCards[0].order === 'number' ? destCards[0].order : 0;
        newOrder = F - 1;
      } else {
        // Dropped between two cards at idx - 1 and idx
        const A = typeof destCards[idx - 1].order === 'number' ? destCards[idx - 1].order : 0;
        const B = typeof destCards[idx].order === 'number' ? destCards[idx].order : 0;
        newOrder = (A + B) / 2;
      }
    }

    const groupChanged = (movedScenario.groupId || null) !== (targetGroupId || null);
    const orderChanged = movedScenario.order !== newOrder;

    if (groupChanged || orderChanged) {
      try {
        await window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios/${movedScenario.id}`).update({
          groupId: targetGroupId || null,
          order: newOrder,
        });
      } catch (err) {
        console.error('Failed to update scenario position:', err);
        showToast && showToast('Failed to reorder scenario ❌');
      }
    }
  }, [draggedScenarioId, dropTarget, lobbyCode, scenarios, showToast]);

  // Handler: Create scenario (writes to rooms/{lobbyCode}/draftLab/scenarios)
  const handleCreateScenario = useCallback(async () => {
    if (!lobbyCode || !window.db) {
      showToast && showToast('Lobby connection required 🌱');
      return;
    }

    const maxOrder = looseScenarios.reduce(
      (max, s) => Math.max(max, typeof s.order === 'number' ? s.order : 0),
      0
    );
    const newOrder = maxOrder + 1;
    const title = `Scenario ${newOrder}`;
    const emptySlots = buildEmptySlots(steps);

    const newScenario = {
      title,
      groupId: null,
      order: newOrder,
      notes: '',
      createdBy: getCurrentUid(),
      createdAt: Date.now(),
      slots: emptySlots,
    };

    try {
      const newRef = window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios`).push();
      await newRef.set(newScenario);
      showToast && showToast(`Created ${title} ✨`);
    } catch (err) {
      console.error('Failed to create scenario:', err);
      showToast && showToast('Failed to create scenario ❌');
    }
  }, [lobbyCode, looseScenarios, steps, getCurrentUid, showToast]);

  // Handler: Duplicate scenario
  const handleDuplicate = useCallback(async (scenario) => {
    if (!lobbyCode || !window.db) {
      showToast && showToast('Lobby connection required 🌱');
      return;
    }

    const targetGroupId = scenario.groupId || null;
    const sameList = scenarios.filter(s => (s.groupId || null) === targetGroupId);
    const maxOrder = sameList.reduce(
      (max, s) => Math.max(max, typeof s.order === 'number' ? s.order : 0),
      0
    );
    const newOrder = maxOrder + 1;

    // Deep copy slots
    const copiedSlots = {};
    steps.forEach(step => {
      const existingSlot = scenario?.slots?.[step.key];
      const alts = existingSlot?.alternates ?? [];
      copiedSlots[step.key] = {
        alternates: Array.isArray(alts) ? [...alts] : [],
      };
    });

    const duplicatedScenario = {
      title: scenario.title || 'Untitled Scenario',
      groupId: targetGroupId,
      order: newOrder,
      notes: scenario.notes || '',
      createdBy: getCurrentUid(),
      createdAt: Date.now(),
      slots: copiedSlots,
    };

    try {
      const newRef = window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios`).push();
      await newRef.set(duplicatedScenario);
      showToast && showToast(`Duplicated “${scenario.title || 'Scenario'}” 📋`);
    } catch (err) {
      console.error('Failed to duplicate scenario:', err);
      showToast && showToast('Failed to duplicate scenario ❌');
    }
  }, [lobbyCode, scenarios, steps, getCurrentUid, showToast]);

  // Handler: Duplicate all selected scenarios from top action bar
  const handleDuplicateSelected = useCallback(async () => {
    if (selectedScenarioIds.length === 0) {
      showToast && showToast('Select one or more scenarios to duplicate 📋');
      return;
    }
    const toDuplicate = scenarios.filter(s => selectedScenarioIds.includes(s.id));
    for (const s of toDuplicate) {
      await handleDuplicate(s);
    }
  }, [selectedScenarioIds, scenarios, handleDuplicate, showToast]);

  // Handler: New group button (top action bar)
  // If scenarios selected: creates new group, moves selected scenarios with order 0, 1, 2..., clears selection.
  // If nothing selected: creates empty group.
  const handleNewGroup = useCallback(async () => {
    if (!lobbyCode || !window.db) {
      showToast && showToast('Lobby connection required 🌱');
      return;
    }

    const nextOrder = groups.reduce(
      (max, g) => Math.max(max, typeof g.order === 'number' ? g.order : 0),
      0
    ) + 1;
    const groupName = `Group ${groups.length + 1}`;

    try {
      const groupRef = window.db.ref(`rooms/${lobbyCode}/draftLab/groups`).push();
      const newGroupId = groupRef.key;
      await groupRef.set({
        name: groupName,
        order: nextOrder,
      });

      if (selectedScenarioIds.length > 0) {
        const selectedList = scenarios
          .filter(s => selectedScenarioIds.includes(s.id))
          .sort((a, b) => (a.order || 0) - (b.order || 0));

        const updates = {};
        selectedList.forEach((s, idx) => {
          updates[`rooms/${lobbyCode}/draftLab/scenarios/${s.id}/groupId`] = newGroupId;
          updates[`rooms/${lobbyCode}/draftLab/scenarios/${s.id}/order`] = idx;
        });

        await window.db.ref().update(updates);
        setSelectedScenarioIds([]);
        showToast && showToast(`Created ${groupName} with ${selectedList.length} scenario${selectedList.length === 1 ? '' : 's'} ✨`);
      } else {
        showToast && showToast(`Created empty ${groupName} 📁`);
      }
    } catch (err) {
      console.error('Failed to create new group:', err);
      showToast && showToast('Failed to create group ❌');
    }
  }, [lobbyCode, groups, selectedScenarioIds, scenarios, showToast]);

  // Handler: Group "+Add" — moves currently-selected scenarios not already in this group into this group
  const handleAddSelectedToGroup = useCallback(async (groupId) => {
    if (!lobbyCode || !window.db) return;
    const toMove = scenarios
      .filter(s => selectedScenarioIds.includes(s.id) && s.groupId !== groupId)
      .sort((a, b) => (a.order || 0) - (b.order || 0));

    if (toMove.length === 0) {
      showToast && showToast('No scenarios from outside this group are selected 🌱');
      return;
    }

    const existingInGroup = scenarios.filter(s => s.groupId === groupId);
    const maxOrderInGroup = existingInGroup.reduce(
      (max, s) => Math.max(max, typeof s.order === 'number' ? s.order : -1),
      -1
    );

    const updates = {};
    toMove.forEach((s, idx) => {
      updates[`rooms/${lobbyCode}/draftLab/scenarios/${s.id}/groupId`] = groupId;
      updates[`rooms/${lobbyCode}/draftLab/scenarios/${s.id}/order`] = maxOrderInGroup + 1 + idx;
    });

    try {
      await window.db.ref().update(updates);
      setSelectedScenarioIds([]);
      showToast && showToast(`Added ${toMove.length} scenario${toMove.length === 1 ? '' : 's'} to group 📁`);
    } catch (err) {
      console.error('Failed to add scenarios to group:', err);
      showToast && showToast('Failed to add scenarios to group ❌');
    }
  }, [lobbyCode, scenarios, selectedScenarioIds, showToast]);

  // Handler: Group "Ungroup" — sets groupId: null for all scenarios in group, appends order to loose list, deletes group doc
  const handleUngroup = useCallback(async (groupId) => {
    if (!lobbyCode || !window.db) return;
    const inGroup = scenarios
      .filter(s => s.groupId === groupId)
      .sort((a, b) => (a.order || 0) - (b.order || 0));

    const maxLooseOrder = looseScenarios.reduce(
      (max, s) => Math.max(max, typeof s.order === 'number' ? s.order : -1),
      -1
    );

    const updates = {};
    inGroup.forEach((s, idx) => {
      updates[`rooms/${lobbyCode}/draftLab/scenarios/${s.id}/groupId`] = null;
      updates[`rooms/${lobbyCode}/draftLab/scenarios/${s.id}/order`] = maxLooseOrder + 1 + idx;
    });

    try {
      if (Object.keys(updates).length > 0) {
        await window.db.ref().update(updates);
      }
      await window.db.ref(`rooms/${lobbyCode}/draftLab/groups/${groupId}`).remove();
      showToast && showToast('Group ungrouped 📂');
    } catch (err) {
      console.error('Failed to ungroup:', err);
      showToast && showToast('Failed to ungroup ❌');
    }
  }, [lobbyCode, scenarios, looseScenarios, showToast]);

  // Handler: Group "Select all" — selects every scenario in that group
  const handleSelectAllInGroup = useCallback((groupId) => {
    const ids = scenarios.filter(s => s.groupId === groupId).map(s => s.id);
    setSelectedScenarioIds(ids);
  }, [scenarios]);

  // Handler: Delete scenario (removes that one scenario doc only)
  const handleDelete = useCallback(async (scenario) => {
    if (!lobbyCode || !window.db) {
      showToast && showToast('Lobby connection required 🌱');
      return;
    }

    try {
      await window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios/${scenario.id}`).remove();
      setSelectedScenarioIds(prev => prev.filter(id => id !== scenario.id));
      showToast && showToast('Scenario deleted 👋');
    } catch (err) {
      console.error('Failed to delete scenario:', err);
      showToast && showToast('Failed to delete scenario ❌');
    }
  }, [lobbyCode, showToast]);

  // Handler: Remove alternate champion from a slot
  const handleRemoveAlternate = useCallback((scenarioId, slotKey, champId) => {
    if (!lobbyCode || !window.db || !scenarioId) return;
    const targetSc = scenarios.find(s => s.id === scenarioId);
    const currentAlts = targetSc?.slots?.[slotKey]?.alternates ?? [];
    const newAlts = currentAlts.filter(id => id !== champId);
    window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios/${scenarioId}/slots/${slotKey}/alternates`).set(newAlts);
  }, [lobbyCode, scenarios]);

  // State for active slot Champion Search Modal
  const [activeSlotPicker, setActiveSlotPicker] = useState(null);

  // Handler: Open modal for a specific slot (either to add or to swap at swapIndex)
  const handleOpenPicker = useCallback((scenarioId, slotKey, currentAlternates, swapIndex = null) => {
    setActiveSlotPicker({
      scenarioId,
      slotKey,
      currentAlternates: currentAlternates || [],
      swapIndex: typeof swapIndex === 'number' ? swapIndex : null,
    });
  }, []);

  // Handler: Select champion from modal
  const handleSelectChampion = useCallback((champId) => {
    if (!activeSlotPicker || !lobbyCode || !window.db) return;
    const { scenarioId, slotKey, currentAlternates, swapIndex } = activeSlotPicker;
    const current = currentAlternates || [];

    let updated;
    if (typeof swapIndex === 'number' && swapIndex >= 0 && swapIndex < current.length) {
      // SWAP MODE: Replace champion at swapIndex, keeping array length and relative order identical
      updated = [...current];
      updated[swapIndex] = champId;
    } else {
      // ADD MODE: Append champion if not already in array
      if (!current.includes(champId)) {
        updated = [...current, champId];
      } else {
        updated = current;
      }
    }

    window.db.ref(`rooms/${lobbyCode}/draftLab/scenarios/${scenarioId}/slots/${slotKey}/alternates`).set(updated);
    setActiveSlotPicker(null);
  }, [activeSlotPicker, lobbyCode]);

  const isDragging = Boolean(draggedScenarioId);
  const isTargetLoose = isDragging && dropTarget?.targetGroupId === null;

  if (!lobbyCode) {
    return (
      <div style={{ padding: 24, textAlign: 'center' }}>
        <div className="cozy-card" style={{ maxWidth: 440, margin: '40px auto', padding: 24 }}>
          <h3 className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 22, marginBottom: 8 }}>
            Draft Lab (beta) 🧪
          </h3>
          <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 14 }}>
            Join or create a lobby first to explore and build draft scenarios collaboratively with your team! 🌿
          </p>
        </div>
      </div>
    );
  }

  return (
    <div onClick={handleBoardClick} style={{ padding: 20, minHeight: '100%' }}>
      {/* Header and Top Action Bar */}
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          marginBottom: 24,
          flexWrap: 'wrap',
          gap: 14,
        }}
      >
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <h1 className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 28, margin: 0 }}>
              Draft Lab (beta) 🧪
            </h1>
          </div>
          <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 14, margin: '4px 0 0 0' }}>
            Explore draft branches, alternate champion picks, and counter-strategies collaboratively
          </p>
        </div>

        {/* Top Action Bar: "+New scenario", "Duplicate", "New group" */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
          <button
            onClick={handleCreateScenario}
            className="cozy-btn"
            style={{
              background: 'var(--accent-orange)',
              color: '#fff',
              border: 'none',
              borderRadius: 12,
              padding: '8px 16px',
              fontFamily: 'Fredoka, sans-serif',
              fontSize: 14,
              fontWeight: 600,
              cursor: 'pointer',
              display: 'flex',
              alignItems: 'center',
              gap: 6,
              boxShadow: '0 2px 4px rgba(196, 132, 90, 0.25)',
            }}
          >
            <span style={{ fontSize: 16, fontWeight: 900 }}>+</span> New scenario
          </button>

          <button
            onClick={handleDuplicateSelected}
            className="cozy-btn"
            title={selectedScenarioIds.length > 0 ? `Duplicate ${selectedScenarioIds.length} selected` : 'Select scenario(s) to duplicate'}
            style={{
              background: 'var(--surface-card)',
              color: 'var(--text-primary)',
              border: '1.5px solid var(--border-default)',
              borderRadius: 12,
              padding: '8px 14px',
              fontFamily: 'Fredoka, sans-serif',
              fontSize: 14,
              fontWeight: 600,
              cursor: 'pointer',
              display: 'flex',
              alignItems: 'center',
              gap: 6,
              boxShadow: '0 2px 4px rgba(0,0,0,0.04)',
              opacity: selectedScenarioIds.length > 0 ? 1 : 0.7,
            }}
          >
            <LabDuplicateIcon size={16} color="var(--text-muted)" />
            Duplicate {selectedScenarioIds.length > 0 ? `(${selectedScenarioIds.length})` : ''}
          </button>

          <button
            onClick={handleNewGroup}
            className="cozy-btn"
            title="Create a new group from selected scenarios or empty"
            style={{
              background: 'var(--surface-card)',
              color: 'var(--accent-orange)',
              border: '1.5px solid var(--accent-orange)',
              borderRadius: 12,
              padding: '8px 14px',
              fontFamily: 'Fredoka, sans-serif',
              fontSize: 14,
              fontWeight: 600,
              cursor: 'pointer',
              display: 'flex',
              alignItems: 'center',
              gap: 6,
              boxShadow: '0 2px 4px rgba(0,0,0,0.04)',
            }}
          >
            <span style={{ fontSize: 16 }}>📁</span> New group
          </button>
        </div>
      </div>

      {/* Groups Section (if any groups exist in rooms/{lobbyCode}/draftLab/groups) */}
      {sortedGroups.map(group => (
        <DraftLabGroup
          key={group.id}
          group={group}
          scenarios={scenarios}
          lobbyCode={lobbyCode}
          selectedScenarioIds={selectedScenarioIds}
          draggedScenarioId={draggedScenarioId}
          dropTarget={dropTarget}
          onDragStart={handleDragStart}
          onDragEnd={handleDragEnd}
          onCardDragOver={handleCardDragOver}
          onContainerDragOver={handleContainerDragOver}
          onDrop={handleDrop}
          onSelectAll={handleSelectAllInGroup}
          onAddSelected={handleAddSelectedToGroup}
          onUngroup={handleUngroup}
          onDuplicate={handleDuplicate}
          onDelete={handleDelete}
          onRemoveAlternate={(scenarioId, slotKey, champId) => handleRemoveAlternate(scenarioId, slotKey, champId)}
          onOpenPicker={handleOpenPicker}
          onCardClick={handleCardClick}
        />
      ))}

      {/* Loose Scenarios Section (groupId === null) */}
      <div style={{ marginBottom: 24 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
          <h3 className="fredoka" style={{ fontSize: 20, color: 'var(--accent-orange)', margin: 0 }}>
            📄 Loose Scenarios
          </h3>
          <span style={{
            background: 'var(--surface-nested)',
            border: '1.5px solid var(--border-default)',
            borderRadius: 14,
            padding: '2px 10px',
            fontSize: 12,
            fontWeight: 800,
            color: 'var(--text-muted)',
            fontFamily: 'Nunito',
          }}>
            {looseScenarios.length} {looseScenarios.length === 1 ? 'scenario' : 'scenarios'}
          </span>
        </div>

        {/* Row of loose scenario cards + dashed create scenario card */}
        <div
          onDragOver={(e) => {
            e.preventDefault();
            handleContainerDragOver(null, e);
          }}
          onDrop={(e) => {
            e.preventDefault();
            handleDrop(null);
          }}
          style={{
            display: 'flex',
            gap: 16,
            overflowX: 'auto',
            padding: '16px 14px 22px 14px',
            margin: '-8px -14px 0 -14px',
            alignItems: 'stretch',
            minHeight: 180,
          }}
        >
          {looseScenarios.map(scenario => {
            const showIndicatorBefore =
              isTargetLoose &&
              dropTarget?.beforeScenarioId === scenario.id &&
              draggedScenarioId !== scenario.id;

            return (
              <React.Fragment key={scenario.id}>
                {showIndicatorBefore && <DropIndicatorPlaceholder />}
                <DraftLabScenarioCard
                  scenario={scenario}
                  lobbyCode={lobbyCode}
                  isSelected={selectedScenarioIds.includes(scenario.id)}
                  isDraggingThis={draggedScenarioId === scenario.id}
                  onDragStart={handleDragStart}
                  onDragEnd={handleDragEnd}
                  onCardDragOver={(sc, e) => handleCardDragOver(sc, null, e)}
                  onDrop={() => handleDrop(null)}
                  onCardClick={handleCardClick}
                  onDuplicate={handleDuplicate}
                  onDelete={handleDelete}
                  onRemoveAlternate={(slotKey, champId) => handleRemoveAlternate(scenario.id, slotKey, champId)}
                  onOpenPicker={handleOpenPicker}
                />
              </React.Fragment>
            );
          })}

          {/* Drop indicator after last card in loose list */}
          {isTargetLoose &&
            dropTarget?.beforeScenarioId === null &&
            looseScenarios.length > 0 &&
            looseScenarios[looseScenarios.length - 1].id !== draggedScenarioId && (
              <DropIndicatorPlaceholder />
          )}

          {/* Dashed "+ Create scenario" card at the end of the loose scenarios row */}
          <CreateScenarioCard onClick={handleCreateScenario} />
        </div>
      </div>

      {/* Champion Search Modal (reusing window.ChampionSearchModal from MyPool / shared) */}
      {window.ChampionSearchModal && (
        <window.ChampionSearchModal
          isOpen={Boolean(activeSlotPicker)}
          onClose={() => setActiveSlotPicker(null)}
          title={
            activeSlotPicker
              ? typeof activeSlotPicker.swapIndex === 'number'
                ? activeSlotPicker.swapIndex === 0
                  ? `Swap Primary: ${activeSlotPicker.slotKey}`
                  : `Swap Alternate #${activeSlotPicker.swapIndex}: ${activeSlotPicker.slotKey}`
                : `Add Alternate: ${activeSlotPicker.slotKey}`
              : "Select Champion"
          }
          subtitle={
            activeSlotPicker && typeof activeSlotPicker.swapIndex === 'number'
              ? `Replace ${activeSlotPicker.currentAlternates[activeSlotPicker.swapIndex] || 'champion'}`
              : "Choose a champion for this draft slot"
          }
          onSelect={handleSelectChampion}
          excludeChampionIds={
            activeSlotPicker
              ? typeof activeSlotPicker.swapIndex === 'number'
                ? (activeSlotPicker.currentAlternates || []).filter((_, i) => i !== activeSlotPicker.swapIndex)
                : activeSlotPicker.currentAlternates || []
              : []
          }
        />
      )}
    </div>
  );
}

// Attach to window
Object.assign(window, { DraftLab });
