import react, { useCallback, useState } from 'react';

import _, { constant } from 'lodash';

import MouseHandler from './mouse-handler';
import Layer from './layer';

import '../theme/viewport.css';
import SingleTouchHandler from './single-touch-handler';
import DoubleTouchHandler from './double-touch-handler';

export interface Point {
  x: number;
  y: number;
}

export interface Translation {
  translate: Point;
}

export interface Scale {
  scale: {
    center: Point;
    factor: number;
  };
}

export type Transformation = Translation | Scale;

// const transform1: Transformation = { translate: { x: 0, y: 1 } };
// const transform2: Transformation = {
//   scale: { center: { x: 10, y: 20 }, factor: 2 },
// };

interface ViewportProps {
  children: any;
}

export interface ViewportState {
  scale: number;
  translation: Point;
}

const Viewport: react.FC<ViewportProps> = (props: ViewportProps) => {
  //console.log(`--- Rendering viewport, props: ${JSON.stringify(props)} ---`);

  const initialState: ViewportState = { scale: 1, translation: { x: 0, y: 0 } };

  const [state, setState] = useState(initialState);

  const genericHandler = (event: any) => {
    console.log('Log - Event: ' + event.type);
    return;
  };

  const applyTransformations = (transformations: Transformation[]) => {
    const newState = transformations.reduce(
      (previousState: ViewportState, transformation): ViewportState => {
        if ('scale' in transformation) {
          return {
            scale: previousState.scale * transformation.scale.factor,
            translation: {
              x:
                previousState.translation.x +
                (previousState.translation.x - transformation.scale.center.x) *
                  (transformation.scale.factor - 1),
              y:
                previousState.translation.y +
                (previousState.translation.y - transformation.scale.center.y) *
                  (transformation.scale.factor - 1),
            },
          };
        }
        return {
          scale: previousState.scale,
          translation: {
            x: previousState.translation.x + transformation.translate.x,
            y: previousState.translation.y + transformation.translate.y,
          },
        };
      },
      state
    );
    setState(newState);
  };

  return (
    <div className='viewport'>
      <MouseHandler applyTransformations={applyTransformations}>
        <SingleTouchHandler applyTransformations={applyTransformations}>
          <DoubleTouchHandler applyTransformations={applyTransformations}>
            <Layer viewportState={state}>{props.children}</Layer>
          </DoubleTouchHandler>
        </SingleTouchHandler>
      </MouseHandler>
    </div>
  );
};

export default Viewport;
