const NON_SUBMITTABLE_INPUT_TYPES = new Set([
  'button',
  'checkbox',
  'file',
  'hidden',
  'image',
  'radio',
  'reset',
  'submit'
]);

interface SelectableField {
  type?: string;
  value: string;
}

interface EnterTarget {
  tagName: string;
  type?: string;
}

/**
 * Whether an input/textarea should have its value selected when focused.
 * Password fields are skipped by default so users can append characters safely.
 */
export function shouldSelectOnFocus(
  element: SelectableField,
  skipPassword = true
): boolean {
  const type = element.type?.toLowerCase() ?? 'text';

  if (skipPassword && type === 'password') {
    return false;
  }

  return element.value.length > 0;
}

/**
 * Finds the first editable text field inside a dialog or form container.
 */
export function findPrimaryDialogField(
  root: ParentNode
): HTMLInputElement | HTMLTextAreaElement | null {
  const input = root.querySelector(
    'input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([disabled])'
  );

  if (input instanceof HTMLInputElement) {
    return input;
  }

  const textarea = root.querySelector('textarea:not([disabled])');

  return textarea instanceof HTMLTextAreaElement ? textarea : null;
}

function readEnterTarget(target: EventTarget | null): EnterTarget | null {
  if (!target || typeof target !== 'object' || !('tagName' in target)) {
    return null;
  }

  const candidate = target as EnterTarget;

  return {
    tagName: String(candidate.tagName).toUpperCase(),
    type: typeof candidate.type === 'string' ? candidate.type : undefined
  };
}

/**
 * Whether Enter in the current event target should trigger a form/dialog submit.
 * Textareas and selects are excluded; IME composition is ignored.
 */
export function shouldSubmitOnEnter(event: Pick<KeyboardEvent, 'key' | 'isComposing'> & {
  target: EventTarget | null;
}): boolean {
  if (event.isComposing || event.key !== 'Enter') {
    return false;
  }

  const target = readEnterTarget(event.target);

  if (!target) {
    return false;
  }

  if (target.tagName === 'TEXTAREA' || target.tagName === 'SELECT') {
    return false;
  }

  if (target.tagName === 'INPUT') {
    return !NON_SUBMITTABLE_INPUT_TYPES.has((target.type ?? 'text').toLowerCase());
  }

  return false;
}
