import React, { useCallback, useMemo, useState } from "react";
import { KrpanoActionProxy } from "../KrpanoActionProxy";
import { useEventCallback } from "../hooks";
import { IKrpanoConfig, NativeKrpanoRendererObject } from "../types";
import { useKrpano } from "../hooks/useKrpano";
import { CurrentSceneContext, KrpanoRendererContext } from "../contexts";

export interface KrpanoProps extends Omit<IKrpanoConfig, "onready" | "target"> {
  className?: string;
  children?: React.ReactNode;
  currentScene?: string;
  target?: string;
  onReady?: (renderer: KrpanoActionProxy) => void;
}

export const Krpano: React.FC<KrpanoProps> = ({
  className,
  children,
  currentScene,
  target = "krpano",
  onReady,
  ...rest
}) => {
  const [renderer, setRenderer] = useState<KrpanoActionProxy | null>(null);
  const onReadyRef = useEventCallback(onReady);
  const onReadyCallback = useCallback(
    (obj: NativeKrpanoRendererObject) => {
      const renderer = new KrpanoActionProxy(obj);
      (window as any)[renderer.name] = renderer;
      setRenderer(renderer);

      if (onReadyRef.current) {
        onReadyRef.current(renderer);
      }
    },
    [onReadyRef]
  );
  const krpanoConfig = useMemo(
    () => ({
      target,
      onready: onReadyCallback,
      ...rest,
    }),
    [target, rest, onReadyCallback]
  );

  useKrpano(krpanoConfig);

  return (
    <KrpanoRendererContext.Provider value={renderer}>
      <CurrentSceneContext.Provider value={currentScene || null}>
        <div
          id={target}
          className={className}
          style={className ? {} : { width: "100vw", height: "100vh" }}
        >
          {renderer ? children : null}
        </div>
      </CurrentSceneContext.Provider>
    </KrpanoRendererContext.Provider>
  );
};
