import * as React from 'react';
import { useState } from 'react';
import { type IContainerModel } from '../../Interfaces/IContainerModel';
import { type IHistoryState } from '../../Interfaces/IHistoryState';
import { USE_EXPERIMENTAL_CANVAS_API } from '../../utils/default';
import { FindContainerById } from '../../utils/itertools';
import { BAR_WIDTH } from '../Bar/Bar';
import { Canvas } from '../Canvas/Canvas';
import { SelectorMode, SVG } from '../SVG/SVG';
import { type ISymbolModel } from '../../Interfaces/ISymbolModel';

interface IViewerProps {
  className: string
  current: IHistoryState
  selectedContainer: IContainerModel | undefined
  selectedSymbol: ISymbolModel | undefined
  margin: number
  isComponentsOpen: boolean
  isSymbolsOpen: boolean
  selectContainer: (containerId: string) => void
}

export interface DrawParams {
  mainContainer: IContainerModel
  selectorMode: SelectorMode
  selectedContainer: IContainerModel | undefined
  selectedSymbol: ISymbolModel | undefined
  containers: Map<string, IContainerModel>
  symbols: Map<string, ISymbolModel>
}

function computeWidth(margin: number): number {
  return window.innerWidth - (window.innerWidth < 768
    ? BAR_WIDTH
    : margin);
}

export function Viewer({
  className,
  current,
  selectedContainer,
  selectedSymbol,
  margin,
  isComponentsOpen,
  isSymbolsOpen,
  selectContainer
}: IViewerProps): JSX.Element {
  const [windowSize, setWindowSize] = useState([
    computeWidth(margin),
    window.innerHeight
  ]);

  React.useEffect(() => {
    function SVGAutoResizer(): void {
      setWindowSize([
        computeWidth(margin),
        window.innerHeight
      ]);
    }

    window.addEventListener('resize', SVGAutoResizer);

    return () => {
      window.removeEventListener('resize', SVGAutoResizer);
    };
  });

  React.useEffect(() => {
    setWindowSize([
      computeWidth(margin),
      window.innerHeight
    ]);
  }, [margin]);

  const mainContainer = FindContainerById(current.containers, current.mainContainer);

  if (mainContainer === undefined) {
    return <></>;
  }

  let selectorMode = SelectorMode.Nothing;
  if (isComponentsOpen) {
    selectorMode = SelectorMode.Containers;
  } else if (isSymbolsOpen) {
    selectorMode = SelectorMode.Symbols;
  }

  const drawParams: DrawParams = {
    mainContainer,
    selectorMode,
    selectedContainer,
    selectedSymbol,
    containers: current.containers,
    symbols: current.symbols
  };

  if (USE_EXPERIMENTAL_CANVAS_API) {
    return (
      <Canvas
        className={className}
        width={window.innerWidth - BAR_WIDTH}
        height={window.innerHeight}
        drawParams={drawParams}
      />
    );
  }

  return (
    <SVG
      className={className}
      viewerWidth={windowSize[0]}
      viewerHeight={windowSize[1]}
      width={mainContainer.properties.width}
      height={mainContainer.properties.height}
      drawParams={drawParams}
      selectContainer={selectContainer}
    />
  );
}
