/**
 * useKeyboardShortcuts.js - Custom hook voor Markdown sneltoetsen
 *
 * Luistert naar keyboard events op een textarea en voegt
 * Markdown opmaak in rond de huidige selectie.
 *
 * Ondersteunde sneltoetsen:
 * - Cmd/Ctrl+B  : Vet (**selectie**)
 * - Cmd/Ctrl+I  : Cursief (*selectie*)
 * - Cmd/Ctrl+K  : Link ([selectie](url))
 * - Cmd/Ctrl+S  : Opslaan
 * - Cmd/Ctrl+Shift+1 : Heading 1 (# )
 * - Cmd/Ctrl+Shift+2 : Heading 2 (## )
 * - Cmd/Ctrl+Shift+3 : Heading 3 (### )
 */

import { useEffect, useCallback } from 'react';

/**
 * @param {React.RefObject} textareaRef - Ref naar de textarea
 * @param {function} onChange - Callback wanneer content wijzigt
 * @param {function} onSave - Callback voor opslaan (Cmd+S)
 */
export function useKeyboardShortcuts(textareaRef, onChange, onSave) {
  const handleKeyDown = useCallback((e) => {
    const textarea = textareaRef.current;
    if (!textarea) return;

    const isMod = e.metaKey || e.ctrlKey;
    if (!isMod) return;

    // Cmd+S: Opslaan
    if (e.key === 's') {
      e.preventDefault();
      onSave();
      return;
    }

    // Cmd+B: Vet
    if (e.key === 'b') {
      e.preventDefault();
      wrapSelection(textarea, '**', '**', onChange);
      return;
    }

    // Cmd+I: Cursief
    if (e.key === 'i') {
      e.preventDefault();
      wrapSelection(textarea, '*', '*', onChange);
      return;
    }

    // Cmd+K: Link
    if (e.key === 'k') {
      e.preventDefault();
      const selected = getSelection(textarea);
      if (selected) {
        wrapSelection(textarea, '[', '](url)', onChange);
      } else {
        insertAtCursor(textarea, '[linktekst](url)', onChange);
      }
      return;
    }

    // Cmd+Shift+1/2/3: Headings
    if (e.shiftKey && ['1', '2', '3'].includes(e.key)) {
      e.preventDefault();
      const level = parseInt(e.key);
      const prefix = '#'.repeat(level) + ' ';
      insertLinePrefix(textarea, prefix, onChange);
      return;
    }
  }, [textareaRef, onChange, onSave]);

  useEffect(() => {
    const textarea = textareaRef.current;
    if (!textarea) return;

    textarea.addEventListener('keydown', handleKeyDown);
    return () => textarea.removeEventListener('keydown', handleKeyDown);
  }, [textareaRef, handleKeyDown]);
}

/**
 * Haalt de huidige selectie uit een textarea.
 */
function getSelection(textarea) {
  return textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
}

/**
 * Wrapt de huidige selectie met prefix en suffix.
 * Als er geen selectie is, wordt placeholder tekst ingevoegd.
 */
function wrapSelection(textarea, prefix, suffix, onChange) {
  const start = textarea.selectionStart;
  const end = textarea.selectionEnd;
  const value = textarea.value;
  const selected = value.substring(start, end);

  const replacement = selected
    ? `${prefix}${selected}${suffix}`
    : `${prefix}tekst${suffix}`;

  const newValue = value.substring(0, start) + replacement + value.substring(end);

  textarea.value = newValue;

  // Plaats cursor na de ingevoegde tekst of selecteer de placeholder
  if (selected) {
    textarea.selectionStart = start + prefix.length;
    textarea.selectionEnd = start + prefix.length + selected.length;
  } else {
    textarea.selectionStart = start + prefix.length;
    textarea.selectionEnd = start + prefix.length + 'tekst'.length;
  }

  textarea.focus();
  onChange(newValue);
}

/**
 * Voegt tekst in op de cursorpositie.
 */
function insertAtCursor(textarea, text, onChange) {
  const start = textarea.selectionStart;
  const value = textarea.value;

  const newValue = value.substring(0, start) + text + value.substring(start);
  textarea.value = newValue;
  textarea.selectionStart = start;
  textarea.selectionEnd = start + text.length;
  textarea.focus();
  onChange(newValue);
}

/**
 * Voegt een prefix toe aan het begin van de huidige regel.
 * Vervangt bestaande heading prefixes als die er al zijn.
 */
function insertLinePrefix(textarea, prefix, onChange) {
  const value = textarea.value;
  const cursor = textarea.selectionStart;

  // Vind het begin van de huidige regel
  const lineStart = value.lastIndexOf('\n', cursor - 1) + 1;
  const lineEnd = value.indexOf('\n', cursor);
  const actualLineEnd = lineEnd === -1 ? value.length : lineEnd;
  const line = value.substring(lineStart, actualLineEnd);

  // Verwijder bestaande heading prefix
  const cleanLine = line.replace(/^#{1,6}\s*/, '');
  const newLine = prefix + cleanLine;

  const newValue = value.substring(0, lineStart) + newLine + value.substring(actualLineEnd);
  textarea.value = newValue;
  textarea.selectionStart = lineStart + prefix.length;
  textarea.selectionEnd = lineStart + newLine.length;
  textarea.focus();
  onChange(newValue);
}
