// Selectores típicos de elementos que son editables o permite foco
const FOCUSABLE_SELECTOR = [
  '[data-cell-focus]',                     // permite marcar manualmente el target dentro de la celda
  'input:not([disabled])',
  'textarea:not([disabled])',
  'select:not([disabled])',
  '[contenteditable="true"]',
  'button:not([disabled])',
  'a[href]',
  '[tabindex]:not([tabindex="-1"])'
].join(',');

// Busca el elemento focuseable dentro de la "celda" destino.
// Puedes poner data-row-index / data-col-index en la propia celda <td> o en el control.
// Este helper cubre ambos casos.

export function findFocusableInCell(row: number, col: number): HTMLElement | null {
  // 1) ¿Hay un control que ya tenga los data-* directamente?
  let el =
    document.querySelector<HTMLElement>(
      `[data-row-index="${row}"][data-col-index="${col}"]${FOCUSABLE_SELECTOR.startsWith('[') ? '' : ''}`
    );

  // Si lo anterior no funcionó o seleccionó un contenedor, intenta:
  if (!el) {
    // 2) ¿Existe una celda contenedora (td/div) con esos data-*?
    const cell = document.querySelector<HTMLElement>(
      `[data-row-index="${row}"][data-col-index="${col}"]`
    );
    if (!cell) return null;

    // 3) Dentro de la celda, busca el primer foco válido
    el = cell.matches(FOCUSABLE_SELECTOR) ? cell : cell.querySelector<HTMLElement>(FOCUSABLE_SELECTOR);
  }

  return el || null;
}

// Da foco y selecciona contenido si procede.
export function focusAndSelect(el: HTMLElement) {
  el.focus?.();

  // Seleccionar tras el foco para evitar que el navegador cancele la selección
  requestAnimationFrame(() => {
    if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
      // Para inputs/textarea
      try {
        // select() funciona en la mayoría; si es type="number", cae en setSelectionRange
        el.select?.();
        // Asegura selección completa si select() no aplica (p.ej. type="number")
        if (typeof (el as any).setSelectionRange === 'function') {
          const val = (el as any).value ?? '';
          (el as any).setSelectionRange(0, String(val).length);
        }
      } catch {
        /* no-op */
      }
    } else if ((el as HTMLElement).isContentEditable) {
      // Para contenteditable
      const range = document.createRange();
      range.selectNodeContents(el);
      const sel = window.getSelection();
      sel?.removeAllRanges();
      sel?.addRange(range);
    }
    // Para select/button/otros focuseables no hacemos selección de texto.
  });
}