<script lang="ts">
  import type { EditorView } from "@codemirror/view";

  interface Props {
    x: number;
    y: number;
    editorView: EditorView;
    onClose: () => void;
  }

  let { x, y, editorView, onClose }: Props = $props();

  // Menu element reference for measuring
  let menuElement: HTMLDivElement | undefined = $state();

  // Adjusted position to keep menu within viewport
  let adjustedX = $derived.by(() => {
    if (!menuElement) return x;
    const menuWidth = menuElement.offsetWidth || 180;
    const maxX = window.innerWidth - menuWidth - 8;
    return Math.min(x, maxX);
  });

  let adjustedY = $derived.by(() => {
    if (!menuElement) return y;
    const menuHeight = menuElement.offsetHeight || 250;
    const maxY = window.innerHeight - menuHeight - 8;
    return Math.min(y, maxY);
  });

  function handleKeydown(event: KeyboardEvent) {
    if (event.key === "Escape") {
      onClose();
    }
  }

  function execCommand(command: "cut" | "copy" | "paste" | "selectAll" | "undo" | "redo") {
    editorView.focus();

    switch (command) {
      case "cut":
        document.execCommand("cut");
        break;
      case "copy":
        document.execCommand("copy");
        break;
      case "paste":
        document.execCommand("paste");
        break;
      case "selectAll":
        editorView.dispatch({
          selection: { anchor: 0, head: editorView.state.doc.length },
        });
        break;
      case "undo":
        import("@codemirror/commands").then(({ undo }) => {
          undo(editorView);
        });
        break;
      case "redo":
        import("@codemirror/commands").then(({ redo }) => {
          redo(editorView);
        });
        break;
    }
    onClose();
  }

  // Check if there's a selection
  let hasSelection = $derived(
    editorView.state.selection.main.from !== editorView.state.selection.main.to
  );
</script>

<svelte:window onkeydown={handleKeydown} />

<!-- svelte-ignore a11y_no_static_element_interactions a11y_click_events_have_key_events -->
<div
  class="menu-overlay"
  onclick={onClose}
  oncontextmenu={(e) => {
    e.preventDefault();
    onClose();
  }}
>
  <!-- svelte-ignore a11y_no_static_element_interactions -->
  <div
    bind:this={menuElement}
    class="menu-content"
    style="left: {adjustedX}px; top: {adjustedY}px;"
    onclick={(e) => e.stopPropagation()}
  >
    <button class="menu-item" onclick={() => execCommand("undo")}>
      <svg class="menu-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M3 10h10a5 5 0 0 1 5 5v2M3 10l4-4M3 10l4 4"
        />
      </svg>
      Undo
      <span class="shortcut">Ctrl+Z</span>
    </button>

    <button class="menu-item" onclick={() => execCommand("redo")}>
      <svg class="menu-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M21 10H11a5 5 0 0 0-5 5v2M21 10l-4-4M21 10l-4 4"
        />
      </svg>
      Redo
      <span class="shortcut">Ctrl+Y</span>
    </button>

    <div class="menu-divider"></div>

    <button class="menu-item" onclick={() => execCommand("cut")} disabled={!hasSelection}>
      <svg class="menu-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M14.121 14.121L19 19m-7-7l7-7m-7 7l-2.879 2.879M12 12L9.121 9.121m0 5.758a3 3 0 1 0-4.243-4.243 3 3 0 0 0 4.243 4.243zm0-5.758a3 3 0 1 0-4.243-4.243 3 3 0 0 0 4.243 4.243z"
        />
      </svg>
      Cut
      <span class="shortcut">Ctrl+X</span>
    </button>

    <button class="menu-item" onclick={() => execCommand("copy")} disabled={!hasSelection}>
      <svg class="menu-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M8 16H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v2m-6 12h8a2 2 0 0 0 2-2v-8a2 2 0 0 0-2-2h-8a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2z"
        />
      </svg>
      Copy
      <span class="shortcut">Ctrl+C</span>
    </button>

    <button class="menu-item" onclick={() => execCommand("paste")}>
      <svg class="menu-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2"
        />
      </svg>
      Paste
      <span class="shortcut">Ctrl+V</span>
    </button>

    <div class="menu-divider"></div>

    <button class="menu-item" onclick={() => execCommand("selectAll")}>
      <svg class="menu-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          stroke-width="2"
          d="M4 5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5z"
        />
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 9h6v6H9z" />
      </svg>
      Select All
      <span class="shortcut">Ctrl+A</span>
    </button>
  </div>
</div>

<style>
  .menu-overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
  }

  .menu-content {
    position: absolute;
    z-index: 50;
    min-width: 180px;
    border-radius: 0.375rem;
    border: 1px solid var(--border-color);
    background-color: var(--bg-secondary);
    padding: 0.25rem 0;
    box-shadow:
      0 10px 15px -3px rgba(0, 0, 0, 0.1),
      0 4px 6px -2px rgba(0, 0, 0, 0.05);
  }

  .menu-item {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    text-align: left;
    font-size: 0.875rem;
    color: var(--text-primary);
    background: transparent;
    border: none;
    cursor: pointer;
    transition: background-color 0.15s ease;
  }

  .menu-item:hover:not(:disabled) {
    background-color: var(--bg-primary);
  }

  .menu-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .menu-divider {
    margin: 0.25rem 0;
    border-top: 1px solid var(--border-color);
  }

  .menu-icon {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
  }

  .shortcut {
    margin-left: auto;
    font-size: 0.75rem;
    color: var(--text-secondary);
  }
</style>
