import * as React from "react";
import { useOrchestrator } from "./../ricos-context/orchestrator-context.js";
import { logInvariant } from "./../_shared/log-invariant.js";
import { useContextSelectorWithValue } from "./../_shared/use-context-selector.js";
import { CursorContext } from "./cursor-context.js";
import { useExecutePrompt } from "./execute-prompt.js";
import { InlineAiContext } from "./inline-ai-context.js";
import { hasKeepablePartialMessages } from "./keepable-partial-messages.js";
import { getPagerAPI } from "./pager-api.js";
import { INLINE_AI_PLUGIN_TYPE } from "./types.js";
const INITIAL_STATE = {
  invocations: {}
};
const InlineAiContextProvider = ({ children, plugins }) => {
  const [inlineAiState, setInlineAiState] = React.useState(INITIAL_STATE);
  const cursorAnchorRef = React.useRef(null);
  const [cursorState, setCursorStateRaw] = React.useState({
    showCursor: false,
    label: null
  });
  const setCursorState = React.useCallback((state) => setCursorStateRaw(state), []);
  const orchestrator = useOrchestrator();
  const inlineAiPluginConfig = plugins.getConfig(INLINE_AI_PLUGIN_TYPE);
  const value = [
    inlineAiState,
    setInlineAiState
  ];
  return /* @__PURE__ */ React.createElement(CursorContext.Provider, { value: { cursorAnchorRef, cursorState, setCursorState } }, /* @__PURE__ */ React.createElement(
    InlineAiContext.Provider,
    {
      value,
      onSelectorContextValue: (x) => {
        orchestrator.inlineAiStateSelectorContextValue = x;
      }
    },
    /* @__PURE__ */ React.createElement(
      SetupExecutePrompt,
      {
        orchestrator,
        aiProjectId: inlineAiPluginConfig.aiProjectId,
        useWixelWidgets: inlineAiPluginConfig.useWixelWidgets
      }
    ),
    children
  ));
};
const SetupExecutePrompt = ({ orchestrator, aiProjectId, useWixelWidgets }) => {
  const executePrompt = useExecutePrompt(aiProjectId, useWixelWidgets);
  if (orchestrator.inlineAiService) {
    orchestrator.inlineAiService.executePrompt = executePrompt;
  } else {
    logInvariant(new Error("Inline AI service is not available"));
  }
  return null;
};
const computeStopTransition = (s, { headless, keepChanges }) => {
  if (s.type === "pending" || s.type === "streaming") {
    const prompt = s.prompt;
    const messages = "messages" in s ? s.messages : [];
    const chunks = "chunks" in s ? s.chunks : [];
    if (keepChanges && hasKeepablePartialMessages(messages)) {
      return { type: "closed", messages, chunks, prompt };
    }
    return headless ? {
      type: "error",
      error: { message: "Cancelled by user", applicationErrorCode: "USER_CANCELLED" },
      messages,
      chunks,
      prompt
    } : { type: "typing", value: prompt };
  }
  return s;
};
const useInlineAiStateWithSelectorContextValue = (selectorContextValue, invocationId, defaultValue) => {
  const [stateSlice, setState] = useContextSelectorWithValue(
    selectorContextValue,
    (ctx) => [ctx?.[0]?.invocations?.[invocationId], ctx?.[1]],
    (a, b) => a[0] === b[0]
  );
  if (!setState) {
    throw new Error("useInlineAiApi must be used within an InlineAiContextProvider");
  }
  const setStateSlice = (newState) => setState((prevState) => {
    const currentInvocationState = prevState.invocations[invocationId] ?? defaultValue;
    const nextInvocationState = typeof newState === "function" ? newState(currentInvocationState) : newState;
    return {
      ...prevState,
      invocations: {
        ...prevState.invocations,
        [invocationId]: nextInvocationState
      }
    };
  });
  const state = stateSlice ?? defaultValue;
  const stop = ({ headless, keepChanges }) => {
    setStateSlice((s) => computeStopTransition(s, { headless, keepChanges }));
  };
  const triggerPreview = () => {
    setStateSlice((s) => {
      if (s.type !== "closed") {
        return s;
      }
      const actionableMessages = s.messages.filter(
        (m) => m.type === "insert" || m.type === "replace"
      );
      if (actionableMessages.length === 0) {
        return s;
      }
      return {
        type: "preview",
        messages: s.messages,
        activeMessageIndex: s.messages.findLastIndex((m) => m.type !== "text"),
        chunks: s.chunks,
        prompt: s.prompt
      };
    });
  };
  return {
    state,
    setState: setStateSlice,
    stop,
    triggerPreview,
    pagerAPI: state?.type !== "preview" ? void 0 : getPagerAPI(
      state.messages,
      state.activeMessageIndex,
      (index) => {
        setStateSlice(
          (prev) => prev && prev.type === "preview" ? { ...prev, activeMessageIndex: index } : prev
        );
      },
      (arg) => {
        setStateSlice(
          (prev) => prev && prev.type === "preview" ? { ...prev, messages: typeof arg === "function" ? arg(prev.messages) : arg } : prev
        );
      }
    )
  };
};
const useInlineAiState = (invocationId, defaultValue) => {
  const context = React.useContext(
    InlineAiContext
  );
  if (!context) {
    throw new Error("useInlineAiApi must be used within an InlineAiContextProvider");
  }
  return useInlineAiStateWithSelectorContextValue(context, invocationId, defaultValue);
};
export {
  InlineAiContextProvider,
  computeStopTransition,
  useInlineAiState,
  useInlineAiStateWithSelectorContextValue
};
//# sourceMappingURL=inline-ai-context-provider.js.map
