// packages/editor/src/components/collab-sidebar/note-thread.js
import clsx from "clsx";
import { useEffect, useRef } from "@wordpress/element";
import { Button } from "@wordpress/components";
import { Stack } from "@wordpress/ui";
import { useDebounce } from "@wordpress/compose";
import { __, _n, sprintf } from "@wordpress/i18n";
import { useDispatch } from "@wordpress/data";
import { __unstableStripHTML as stripHTML } from "@wordpress/dom";
import {
  store as blockEditorStore,
  privateApis as blockEditorPrivateApis
} from "@wordpress/block-editor";
import { AddNote } from "./add-note.mjs";
import { Note } from "./note.mjs";
import { NoteCard } from "./note-card.mjs";
import { NoteForm } from "./note-form.mjs";
import { FloatingContainer } from "./floating-container.mjs";
import {
  focusNoteThread,
  getNoteExcerpt,
  scrollNoteThreadIntoView
} from "./utils.mjs";
import { store as editorStore } from "../../store/index.mjs";
import { unlock } from "../../lock-unlock.mjs";
import { jsx, jsxs } from "react/jsx-runtime";
var { useBlockElement } = unlock(blockEditorPrivateApis);
function NoteThread({
  note,
  onEditNote,
  onAddReply,
  onDeleteNote,
  isSelected,
  sidebarRef,
  floating,
  onKeyDown
}) {
  const isFloating = !!floating;
  const { toggleBlockHighlight, selectBlock, toggleBlockSpotlight } = unlock(
    useDispatch(blockEditorStore)
  );
  const { selectNote } = unlock(useDispatch(editorStore));
  const relatedBlockElement = useBlockElement(note.blockClientId);
  const debouncedToggleBlockHighlight = useDebounce(
    toggleBlockHighlight,
    50
  );
  const floatingRef = useRef(null);
  const isKeyboardTabbingRef = useRef(false);
  const registerThread = floating?.registerThread;
  const unregisterThread = floating?.unregisterThread;
  useEffect(() => {
    const floatingEl = floatingRef.current;
    if (floatingEl && registerThread) {
      registerThread(note.id, relatedBlockElement, floatingEl);
    }
    return () => unregisterThread?.(note.id);
  }, [relatedBlockElement, note.id, registerThread, unregisterThread]);
  useEffect(() => {
    if (!isSelected || note.id === "new") {
      return;
    }
    scrollNoteThreadIntoView(note.id, sidebarRef.current);
  }, [isSelected, floating?.y, note.id, sidebarRef]);
  const onMouseEnter = () => {
    debouncedToggleBlockHighlight(note.blockClientId, true);
  };
  const onMouseLeave = () => {
    debouncedToggleBlockHighlight(note.blockClientId, false);
  };
  const onFocus = () => {
    toggleBlockHighlight(note.blockClientId, true);
  };
  const onBlur = (event) => {
    if (!document.hasFocus()) {
      return;
    }
    const isNoteFocused = event.relatedTarget?.closest(
      ".editor-collab-sidebar-panel__thread"
    );
    const isDialogFocused = event.relatedTarget?.closest('[role="dialog"]');
    const isTabbing = isKeyboardTabbingRef.current;
    if (isNoteFocused && !isTabbing) {
      return;
    }
    if (isDialogFocused) {
      return;
    }
    if (isTabbing && event.currentTarget.contains(event.relatedTarget)) {
      return;
    }
    toggleBlockHighlight(note.blockClientId, false);
    onDeselectNote();
  };
  const onSelectNote = () => {
    if (isSelected) {
      return;
    }
    selectNote(note.id);
    focusNoteThread(note.id, sidebarRef.current);
    toggleBlockSpotlight(note.blockClientId, true);
    if (!!note.blockClientId) {
      selectBlock(note.blockClientId, null);
    }
  };
  const onDeselectNote = () => {
    selectNote(void 0);
    toggleBlockSpotlight(note.blockClientId, false);
  };
  const handleResolve = () => {
    onEditNote({ id: note.id, status: "approved" });
    onDeselectNote();
    if (isFloating) {
      relatedBlockElement?.focus();
    } else {
      focusNoteThread(note.id, sidebarRef.current);
    }
  };
  const allReplies = note?.reply || [];
  const lastReply = allReplies.length > 0 ? allReplies[allReplies.length - 1] : void 0;
  const restReplies = allReplies.length > 0 ? allReplies.slice(0, -1) : [];
  const noteExcerpt = getNoteExcerpt(
    stripHTML(note.content?.rendered),
    10
  );
  const ariaLabel = !!note.blockClientId ? sprintf(
    // translators: %s: note excerpt
    __("Note: %s"),
    noteExcerpt
  ) : sprintf(
    // translators: %s: note excerpt
    __("Original block deleted. Note: %s"),
    noteExcerpt
  );
  if (isFloating && note.id === "new") {
    return /* @__PURE__ */ jsx(
      AddNote,
      {
        onSubmit: onAddReply,
        sidebarRef,
        floating: { y: floating.y, ref: floatingRef }
      }
    );
  }
  return /* @__PURE__ */ jsxs(
    FloatingContainer,
    {
      floating: isFloating ? { y: floating.y, ref: floatingRef } : void 0,
      className: clsx("editor-collab-sidebar-panel__thread", {
        "is-selected": isSelected
      }),
      id: `note-thread-${note.id}`,
      gap: "md",
      onClick: onSelectNote,
      onMouseEnter,
      onMouseLeave,
      onFocus,
      onBlur,
      onKeyUp: (event) => {
        if (event.key === "Tab") {
          isKeyboardTabbingRef.current = false;
        }
      },
      onKeyDown: (event) => {
        if (event.key === "Tab") {
          isKeyboardTabbingRef.current = true;
        } else {
          onKeyDown(event);
        }
      },
      tabIndex: 0,
      role: "treeitem",
      "aria-label": ariaLabel,
      "aria-expanded": isSelected,
      children: [
        /* @__PURE__ */ jsx(
          Button,
          {
            className: "editor-collab-sidebar-panel__skip-to-note",
            variant: "secondary",
            size: "compact",
            onClick: () => {
              focusNoteThread(note.id, sidebarRef.current, "textarea");
            },
            children: __("Add new reply")
          }
        ),
        !note.blockClientId && /* @__PURE__ */ jsx("p", { className: "editor-collab-sidebar-panel__deleted-block-notice", children: __("Original block deleted.") }),
        /* @__PURE__ */ jsx(
          Note,
          {
            note,
            isSelected,
            onEditNote,
            onDeleteNote,
            onResolve: handleResolve
          }
        ),
        isSelected && allReplies.map((reply) => /* @__PURE__ */ jsx(
          Note,
          {
            note: reply,
            parentNote: note,
            isSelected,
            onEditNote,
            onDeleteNote
          },
          reply.id
        )),
        !isSelected && restReplies.length > 0 && /* @__PURE__ */ jsx(
          Stack,
          {
            direction: "row",
            align: "center",
            justify: "space-between",
            className: "editor-collab-sidebar-panel__more-reply-separator",
            children: /* @__PURE__ */ jsx(
              Button,
              {
                size: "compact",
                variant: "tertiary",
                className: "editor-collab-sidebar-panel__more-reply-button",
                onClick: (event) => {
                  event.stopPropagation();
                  onSelectNote();
                },
                children: sprintf(
                  // translators: %s: number of replies.
                  _n(
                    "%s more reply",
                    "%s more replies",
                    restReplies.length
                  ),
                  restReplies.length
                )
              }
            )
          }
        ),
        !isSelected && lastReply && /* @__PURE__ */ jsx(
          Note,
          {
            note: lastReply,
            parentNote: note,
            isSelected: false,
            onEditNote,
            onDeleteNote
          }
        ),
        isSelected && /* @__PURE__ */ jsx(NoteCard, { role: "treeitem", children: /* @__PURE__ */ jsx(
          NoteForm,
          {
            onSubmit: (inputComment) => {
              if ("approved" === note.status) {
                onEditNote({
                  id: note.id,
                  status: "hold",
                  content: inputComment
                });
              } else {
                onAddReply({
                  content: inputComment,
                  parent: note.id
                });
              }
            },
            onCancel: (event) => {
              event.stopPropagation();
              onDeselectNote();
              focusNoteThread(note.id, sidebarRef.current);
            },
            labels: {
              submit: "approved" === note.status ? __("Reopen & Reply") : __("Reply"),
              input: sprintf(
                // translators: %1$s: note identifier, %2$s: author name
                __("Reply to note %1$s by %2$s"),
                note.id,
                note.author_name
              )
            }
          }
        ) }),
        !!note.blockClientId && /* @__PURE__ */ jsx(
          Button,
          {
            className: "editor-collab-sidebar-panel__skip-to-block",
            variant: "secondary",
            size: "compact",
            onClick: (event) => {
              event.stopPropagation();
              relatedBlockElement?.focus();
            },
            children: __("Back to block")
          }
        )
      ]
    }
  );
}
export {
  NoteThread
};
//# sourceMappingURL=note-thread.mjs.map
