import type { LineTimeSerie, LineOptions } from 'line-pod';
import { LinePod } from 'line-pod';
// import { AxisRange } from '@chartwerk/core/dist/types';

import { useEffect, useRef, useState, PropsWithChildren, forwardRef } from 'react';

import * as _ from 'lodash';

export type AxisRange = [number, number] | undefined;
export type ChartwerkLinePodProps = {
  id: string;
  series: LineTimeSerie[];
  options: LineOptions;
  className?: string;
  // TODO: callback types should be exported from chartwerk
  onZoomIn?: (ranges: AxisRange[]) => void;
  onZoomOut?: (centers: { x: number, y: number }) => void;
  onMouseMove?: (event: any) => void;
  onMouseOut?: () => void;
  onLegendClick?: (idx: number) => void,
  onPanning?: (event: { ranges: AxisRange[], d3Event: any }) => void;
  onPanningEnd?: (ranges: AxisRange[]) => void;
  onContextMenu?: (evt: any) => void;
  onSharedCrosshairMove?: (evt: any) => void;
  onRenderStart?: () => void,
  onRenderEnd?: () => void,
}

export const ChartwerkLinePod = forwardRef<HTMLDivElement, PropsWithChildren<ChartwerkLinePodProps>>((props, ref) => {
  const [pod, setPod] = useState<LinePod | null>(null);
  const [hack, setHack] = useState<number | null>(null);

  const chartRef = useRef(null);
  const chart = chartRef.current;

  useEffect(() => {
    // this function will be called on component unmount
    return () => {
      if (pod === null) {
        return;
      }

      console.log('remove chart');

      // @ts-ignore
      pod.removeEventListeners();
    }
  }, []);

  useEffect(() => {
    if (chart === null) {
      return;
    }

    let eventsCallbacks = _.cloneDeep(props.options.eventsCallbacks || {});
    if (props.onZoomIn) {
      eventsCallbacks.zoomIn = props.onZoomIn;
    }
    if (props.onZoomOut) {
      eventsCallbacks.zoomOut = props.onZoomOut;
    }
    if (props.onMouseMove) {
      eventsCallbacks.mouseMove = props.onMouseMove;
    }
    if (props.onMouseOut) {
      eventsCallbacks.mouseOut = props.onMouseOut;
    }
    if (props.onLegendClick) {
      eventsCallbacks.onLegendClick = props.onLegendClick;
    }
    if (props.onPanning) {
      eventsCallbacks.panning = props.onPanning;
    }
    if (props.onPanningEnd) {
      eventsCallbacks.panningEnd = props.onPanningEnd;
    }
    if (props.onContextMenu) {
      eventsCallbacks.contextMenu = props.onContextMenu;
    }
    if (props.onSharedCrosshairMove) {
      eventsCallbacks.sharedCrosshairMove = props.onSharedCrosshairMove;
    }
    if (props.onRenderStart) {
      eventsCallbacks.renderStart = props.onRenderStart;
    }

    if (pod === null) {
      console.log('create chart');

      const newPod = new LinePod(
        // @ts-ignore
        chart,
        props.series,
        {
          ...props.options,
          eventsCallbacks,
        }
      );
      setPod(
        newPod
      );
      console.log('initial chart render');
      newPod.render();
    } else {
      console.log('update chart');
      pod.updateData(props.series, {
        ...props.options,
        eventsCallbacks,
      });
    }
  }, [chart, pod, props.id, props.series, props.options]);

  // TODO: it's a hack to render the LinePod right after the div appears in DOM
  setTimeout(() => {
    if (hack === null) {
      setHack(1);
    }
  }, 1);

  return (
    <div ref={ref}>
      <div id={props.id} className={props.className} ref={chartRef}></div>
      {props.children}
    </div>
  );
});
