import React, { useState, useEffect } from 'react';
import Resizable from 're-resizable';
import Draggable from 'react-draggable';
import cx from 'classnames';
import styles from './styles.scss';
import { ACTIONS, CAMERADOCK_POSITION } from '../layout/enums';
import DropAreaContainer from './drop-areas/container';
import VideoProviderContainer from '/imports/ui/components/video-provider/container';

const WebcamComponent = ({
  cameraDock,
  swapLayout,
  newLayoutContextDispatch,
  fullscreen,
}) => {
  const [isResizing, setIsResizing] = useState(false);
  const [isDragging, setIsDragging] = useState(false);
  const [isFullscreen, setIsFullScreen] = useState(false);
  const [resizeStart, setResizeStart] = useState({ width: 0, height: 0 });

  useEffect(() => {
    setIsFullScreen(fullscreen.group === 'webcams');
  }, [fullscreen]);

  const onResizeHandle = (deltaWidth, deltaHeight) => {
    if (cameraDock.resizableEdge.top || cameraDock.resizableEdge.bottom) {
      newLayoutContextDispatch(
        {
          type: ACTIONS.SET_CAMERA_DOCK_SIZE,
          value: {
            width: cameraDock.width,
            height: resizeStart.height + deltaHeight,
            browserWidth: window.innerWidth,
            browserHeight: window.innerHeight,
          },
        },
      );
    }
    if (cameraDock.resizableEdge.left || cameraDock.resizableEdge.right) {
      newLayoutContextDispatch(
        {
          type: ACTIONS.SET_CAMERA_DOCK_SIZE,
          value: {
            width: resizeStart.width + deltaWidth,
            height: cameraDock.height,
            browserWidth: window.innerWidth,
            browserHeight: window.innerHeight,
          },
        },
      );
    }
  };

  const handleWebcamDragStart = () => {
    setIsDragging(true);
    document.body.style.overflow = 'hidden';
    newLayoutContextDispatch({
      type: ACTIONS.SET_CAMERA_DOCK_IS_DRAGGING,
      value: true,
    });
  };

  const handleWebcamDragStop = (e) => {
    setIsDragging(false);
    document.body.style.overflow = 'auto';

    if (Object.values(CAMERADOCK_POSITION).includes(e.target.id)) {
      newLayoutContextDispatch({
        type: ACTIONS.SET_CAMERA_DOCK_POSITION,
        value: e.target.id,
      });
    }

    newLayoutContextDispatch({
      type: ACTIONS.SET_CAMERA_DOCK_IS_DRAGGING,
      value: false,
    });
  };

  const draggableClassName = cx({
    [styles.draggable]: cameraDock.isDraggable && !isFullscreen && !isDragging,
    [styles.draggingBg]: isDragging,
  });

  return (
    <>
      {isDragging ? <DropAreaContainer /> : null}
      <Draggable
        handle="video"
        bounds="html"
        onStart={handleWebcamDragStart}
        onStop={handleWebcamDragStop}
        onMouseDown={
          cameraDock.isDraggable ? (e) => e.preventDefault() : undefined
        }
        disabled={!cameraDock.isDraggable || isResizing || isFullscreen}
        position={
          {
            x: cameraDock.left,
            y: cameraDock.top,
          }
        }
      >
        <Resizable
          minWidth={cameraDock.minWidth}
          minHeight={cameraDock.minHeight}
          maxWidth={cameraDock.maxWidth}
          size={{
            width: cameraDock.width,
            height: cameraDock.height,
          }}
          handleWrapperClass={styles.resizeWrapper}
          onResizeStart={() => {
            setIsResizing(true);
            setResizeStart({ width: cameraDock.width, height: cameraDock.height });
          }}
          onResize={(e, direction, ref, d) => {
            onResizeHandle(d.width, d.height);
          }}
          onResizeStop={() => {
            setResizeStart({ width: 0, height: 0 });
            setTimeout(() => setIsResizing(false), 500);
          }}
          enable={{
            top: !isFullscreen && !isDragging && cameraDock.resizableEdge.top,
            bottom: !isFullscreen && !isDragging && cameraDock.resizableEdge.bottom,
            left: !isFullscreen && !isDragging && cameraDock.resizableEdge.left,
            right: !isFullscreen && !isDragging && cameraDock.resizableEdge.right,
            topLeft: false,
            topRight: false,
            bottomLeft: false,
            bottomRight: false,
          }}
          style={{
            position: 'absolute',
            zIndex: cameraDock.zIndex,
          }}
        >
          <div
            id="cameraDock"
            className={draggableClassName}
            draggable={cameraDock.isDraggable && !isFullscreen ? 'true' : undefined}
            style={{
              width: cameraDock.width,
              height: cameraDock.height,
              opacity: isDragging ? 0.5 : undefined,
            }}
          >
            <VideoProviderContainer
              {...{
                swapLayout,
                cameraDock,
              }}
            />
          </div>
        </Resizable>
      </Draggable>
    </>
  );
};

export default WebcamComponent;
