"use client";

import { type FC, memo, type PropsWithChildren, useEffect } from "react";
import {
  type AssistantClient,
  type AuiConfig,
  useAui,
} from "@assistant-ui/store";
import type { AssistantRuntime } from "@assistant-ui/core";
import { AssistantProviderBase } from "@assistant-ui/core/react";
import { ThreadPrimitiveViewportProvider } from "../context/providers/ThreadViewportProvider";
import { DevToolsProviderApi } from "../devtools/DevToolsHooks";

export namespace AssistantRuntimeProvider {
  export type Props = PropsWithChildren<{
    /**
     * The assistant runtime to expose to descendants. Build one with
     * `useLocalRuntime`, `useExternalStoreRuntime`, or
     * `useAssistantTransportRuntime`.
     */
    runtime: AssistantRuntime;

    /**
     * Optional parent `AssistantClient` whose scopes are inherited by the
     * client created for this runtime. Use this when nesting an
     * `AssistantRuntimeProvider` inside another assistant context. Omit this
     * prop when there is no parent client.
     * @defaultValue undefined
     */
    aui?: AssistantClient;

    /**
     * Optional extra scopes provided alongside the runtime's `threads`
     * scope; build with `AuiConfig`.
     */
    config?: AuiConfig;
  }>;
}

const DevToolsRegistration: FC = () => {
  const aui = useAui();
  useEffect(() => {
    if (typeof process === "undefined" || process.env.NODE_ENV === "production")
      return;
    return DevToolsProviderApi.register(aui);
  }, [aui]);
  return null;
};

export const AssistantRuntimeProviderImpl: FC<
  AssistantRuntimeProvider.Props
> = ({ children, aui, config, runtime }) => {
  return (
    <AssistantProviderBase runtime={runtime} aui={aui ?? null} config={config}>
      <DevToolsRegistration />
      {/* TODO temporarily allow accessing viewport state from outside the viewport */}
      {/* TODO figure out if this behavior should be deprecated, since it is quite hacky */}
      <ThreadPrimitiveViewportProvider>
        {children}
      </ThreadPrimitiveViewportProvider>
    </AssistantProviderBase>
  );
};

export const AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
