// src/createPlotComponent.tsx
import { tryCatch } from "@dschz/try-catch";
import {
  createEffect,
  createSignal,
  mergeProps,
  onCleanup,
  onMount,
  splitProps
} from "solid-js";

// src/constants.ts
var PLOT_COMPONENT_EVENT_NAMES = [
  "onAfterExport",
  "onAfterPlot",
  "onAnimated",
  "onAnimatingFrame",
  "onAnimationInterrupted",
  "onAutoSize",
  "onBeforeExport",
  "onBeforePlot",
  "onClick",
  "onClickAnnotation",
  "onDeselect",
  "onDoubleClick",
  "onEvent",
  "onFramework",
  "onHover",
  "onLegendClick",
  "onLegendDoubleClick",
  "onRedraw",
  "onRelayout",
  "onRelayouting",
  "onRestyle",
  "onSelected",
  "onSelecting",
  "onSliderChange",
  "onSliderEnd",
  "onSliderStart",
  "onSunburstClick",
  "onTransitioning",
  "onTransitionInterrupted",
  "onUnhover"
];

// src/utils.ts
var convertComponentEventNameToPlotlyEventName = (eventName) => {
  const eventNameWithoutOnPrefix = eventName.substring(2);
  return `plotly_${eventNameWithoutOnPrefix.toLowerCase()}`;
};
var attachComponentEvents = (plotElement, componentEventMap) => {
  for (const eventName in componentEventMap) {
    const eventHandler = componentEventMap[eventName];
    if (!eventHandler) continue;
    const plotlyEventName = convertComponentEventNameToPlotlyEventName(
      eventName
    );
    plotElement.on(plotlyEventName, eventHandler);
  }
};
var removeComponentEvents = (plotElement, componentEventMap) => {
  for (const eventName in componentEventMap) {
    const componentEventName = eventName;
    const eventHandler = componentEventMap[componentEventName];
    if (!eventHandler) continue;
    const plotlyEventName = convertComponentEventNameToPlotlyEventName(componentEventName);
    plotElement.removeAllListeners(plotlyEventName);
  }
};
var getFigureData = (plotElement) => {
  const pElem = plotElement;
  const figureData = {
    data: pElem.data,
    layout: pElem.layout,
    frames: pElem._transitionData?._frames || []
  };
  return figureData;
};

// src/createPlotComponent.tsx
var createPlotComponent = (Plotly) => (props) => {
  const _props = mergeProps(
    {
      id: "solid-plotly",
      config: {},
      data: [],
      frames: [],
      layout: {},
      useResize: true,
      style: {
        position: "relative",
        display: "inline-block"
      }
    },
    props
  );
  let container;
  let plotElement;
  const [initialized, setInitialized] = createSignal(false);
  const [containerProps] = splitProps(_props, ["id", "class", "style", "ref"]);
  const [eventProps] = splitProps(_props, PLOT_COMPONENT_EVENT_NAMES);
  const [plotProps] = splitProps(_props, [
    "data",
    "layout",
    "config",
    "onInitialized",
    "onPurge",
    "onUpdate",
    "onError",
    "onResize",
    "useResize"
  ]);
  const layout = () => plotProps.useResize ? { ...plotProps.layout, autosize: true } : plotProps.layout;
  const config = () => plotProps.useResize ? { ...plotProps.config, responsive: true } : plotProps.config;
  onMount(async () => {
    const [error, element] = await tryCatch(
      Plotly.newPlot(container, plotProps.data, layout(), config())
    );
    if (error) {
      plotProps.onError?.(error);
      return;
    }
    Plotly.Plots.resize(element);
    attachComponentEvents(element, eventProps);
    plotProps.onInitialized?.(getFigureData(element), element);
    plotElement = element;
    setInitialized(true);
  });
  createEffect(() => {
    if (!initialized()) return;
    const updatePlot = async () => {
      const [error, element] = await tryCatch(
        Plotly.react(container, plotProps.data, layout(), config())
      );
      if (error) {
        plotProps.onError?.(error);
        return;
      }
      plotProps.onUpdate?.(getFigureData(element), element);
    };
    void updatePlot();
  });
  createEffect(() => {
    if (!initialized() || !plotProps.useResize) return;
    const resizeHandler = () => {
      Plotly.Plots.resize(plotElement);
      plotProps.onResize?.();
    };
    const resizeObserver = new ResizeObserver(resizeHandler);
    resizeObserver.observe(container);
    onCleanup(() => {
      resizeObserver.disconnect();
    });
  });
  onCleanup(() => {
    if (!initialized()) return;
    removeComponentEvents(plotElement, eventProps);
    Plotly.purge(plotElement);
    plotProps.onPurge?.(getFigureData(plotElement), plotElement);
    setInitialized(false);
  });
  return <div
    id={containerProps.id}
    class={containerProps.class}
    style={containerProps.style}
    ref={(el) => {
      container = el;
      containerProps.ref?.(el);
    }}
  />;
};
export {
  createPlotComponent
};
