// packages/editor/src/components/collab-sidebar/notes.js
import { useEffect, useMemo } from "@wordpress/element";
import { __ } from "@wordpress/i18n";
import { useSelect, useDispatch } from "@wordpress/data";
import { Stack } from "@wordpress/ui";
import {
  store as blockEditorStore,
  privateApis as blockEditorPrivateApis
} from "@wordpress/block-editor";
import { unlock } from "../../lock-unlock.mjs";
import { NoteThread } from "./note-thread.mjs";
import { focusNoteThread } from "./utils.mjs";
import { useFloatingBoard, useNoteActions } from "./hooks.mjs";
import { AddNote } from "./add-note.mjs";
import { store as editorStore } from "../../store/index.mjs";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var { useBlockElement } = unlock(blockEditorPrivateApis);
function Notes({ notes, sidebarRef, isFloating = false, styles }) {
  const {
    onCreate: onAddReply,
    onEdit: onEditNote,
    onDelete
  } = useNoteActions();
  const { selectNote } = unlock(useDispatch(editorStore));
  const { selectBlock, toggleBlockSpotlight } = unlock(
    useDispatch(blockEditorStore)
  );
  const { blockNoteId, selectedBlockClientId, orderedBlockIds } = useSelect(
    (select) => {
      const {
        getBlockAttributes,
        getSelectedBlockClientId,
        getClientIdsWithDescendants
      } = select(blockEditorStore);
      const clientId = getSelectedBlockClientId();
      return {
        blockNoteId: clientId ? getBlockAttributes(clientId)?.metadata?.noteId : null,
        selectedBlockClientId: clientId,
        orderedBlockIds: getClientIdsWithDescendants()
      };
    },
    []
  );
  const { selectedNote, noteFocused } = useSelect((select) => {
    const { getSelectedNote, isNoteFocused } = unlock(
      select(editorStore)
    );
    return {
      selectedNote: getSelectedNote(),
      noteFocused: isNoteFocused()
    };
  }, []);
  const relatedBlockElement = useBlockElement(selectedBlockClientId);
  const threads = useMemo(() => {
    if (!isFloating || selectedNote !== "new") {
      return notes;
    }
    const newNoteThread = {
      id: "new",
      blockClientId: selectedBlockClientId,
      content: { rendered: "" }
    };
    const out = [];
    orderedBlockIds.forEach((blockId) => {
      if (blockId === selectedBlockClientId) {
        out.push(newNoteThread);
      } else {
        const threadForBlock = notes.find(
          (t) => t.blockClientId === blockId
        );
        if (threadForBlock) {
          out.push(threadForBlock);
        }
      }
    });
    return out;
  }, [
    notes,
    isFloating,
    selectedNote,
    selectedBlockClientId,
    orderedBlockIds
  ]);
  const handleDelete = async (note) => {
    const currentIndex = threads.findIndex((t) => t.id === note.id);
    const nextThread = threads[currentIndex + 1];
    const prevThread = threads[currentIndex - 1];
    await onDelete(note);
    if (note.parent !== 0) {
      selectNote(note.parent);
      focusNoteThread(note.parent, sidebarRef.current);
      return;
    }
    const adjacentThread = nextThread ?? prevThread;
    if (adjacentThread) {
      selectNote(adjacentThread.id);
      focusNoteThread(adjacentThread.id, sidebarRef.current);
      if (adjacentThread.blockClientId) {
        toggleBlockSpotlight(adjacentThread.blockClientId, true);
        selectBlock(adjacentThread.blockClientId, null);
      }
    } else {
      selectNote(void 0);
      toggleBlockSpotlight(note.blockClientId, false);
      relatedBlockElement?.focus();
    }
  };
  useEffect(() => {
    selectNote(blockNoteId ?? void 0);
  }, [blockNoteId, selectNote]);
  useEffect(() => {
    if (noteFocused && selectedNote) {
      focusNoteThread(
        selectedNote,
        sidebarRef.current,
        selectedNote === "new" ? "textarea" : void 0
      );
      selectNote(selectedNote);
    }
  }, [noteFocused, selectedNote, selectNote, sidebarRef]);
  const { notePositions, registerThread, unregisterThread } = useFloatingBoard({
    threads,
    selectedNoteId: selectedNote,
    isFloating,
    sidebarRef
  });
  const hasThreads = Array.isArray(threads) && threads.length > 0;
  const navigate = (event, thread, isSelected) => {
    if (event.defaultPrevented) {
      return;
    }
    const currentIndex = threads.findIndex((t) => t.id === thread.id);
    const isSelfTarget = event.currentTarget === event.target;
    if ((event.key === "Enter" || event.key === "ArrowRight") && isSelfTarget && !isSelected) {
      selectNote(thread.id);
      if (!!thread.blockClientId) {
        selectBlock(thread.blockClientId, null);
        toggleBlockSpotlight(thread.blockClientId, true);
      }
    } else if ((event.key === "Enter" || event.key === "ArrowLeft") && isSelfTarget && isSelected || event.key === "Escape") {
      selectNote(void 0);
      if (thread.blockClientId) {
        toggleBlockSpotlight(thread.blockClientId, false);
      }
      focusNoteThread(thread.id, sidebarRef.current);
    } else if (event.key === "ArrowDown" && currentIndex < threads.length - 1 && isSelfTarget) {
      focusNoteThread(
        threads[currentIndex + 1].id,
        sidebarRef.current
      );
    } else if (event.key === "ArrowUp" && currentIndex > 0 && isSelfTarget) {
      focusNoteThread(
        threads[currentIndex - 1].id,
        sidebarRef.current
      );
    } else if (event.key === "Home" && isSelfTarget) {
      focusNoteThread(threads[0].id, sidebarRef.current);
    } else if (event.key === "End" && isSelfTarget) {
      focusNoteThread(
        threads[threads.length - 1].id,
        sidebarRef.current
      );
    }
  };
  return /* @__PURE__ */ jsx(
    Stack,
    {
      className: "editor-collab-sidebar-panel",
      style: styles,
      role: "tree",
      direction: "column",
      gap: "md",
      justify: "flex-start",
      ref: (node) => {
        if (node) {
          sidebarRef.current = node;
        }
      },
      "aria-label": isFloating ? __("Unresolved notes") : __("All notes"),
      children: !hasThreads && !isFloating ? /* @__PURE__ */ jsx(AddNote, { onSubmit: onAddReply, sidebarRef }) : /* @__PURE__ */ jsxs(Fragment, { children: [
        !isFloating && selectedNote === "new" && /* @__PURE__ */ jsx(
          AddNote,
          {
            onSubmit: onAddReply,
            sidebarRef
          }
        ),
        threads.map((thread) => /* @__PURE__ */ jsx(
          NoteThread,
          {
            note: thread,
            onAddReply,
            onDeleteNote: handleDelete,
            onEditNote,
            isSelected: selectedNote === thread.id,
            sidebarRef,
            floating: isFloating ? {
              y: notePositions[thread.id],
              registerThread,
              unregisterThread
            } : void 0,
            onKeyDown: (event) => navigate(
              event,
              thread,
              selectedNote === thread.id
            )
          },
          thread.id
        ))
      ] })
    }
  );
}
export {
  Notes
};
//# sourceMappingURL=notes.mjs.map
