/**
 * @author Timur Kuzhagaliyev <tim.kuzh@gmail.com>
 * @copyright 2020
 * @license MIT
 */

import React from 'react';
import { useDragLayer } from 'react-dnd';
import { Nullable } from 'tsdef';

import { ChonkyDndFileEntryItem, ChonkyDndFileEntryType } from '../../types/dnd.types';
import { makeGlobalChonkyStyles } from '../../util/styles';

export interface DnDFileListDragLayerProps {}

const layerStyles: React.CSSProperties = {
  position: 'fixed',
  pointerEvents: 'none',
  zIndex: 100,
  left: 0,
  top: 0,
  width: '100%',
  height: '100%',
};
const getItemStyles = (
  initialCursorOffset: Nullable<{ x: number; y: number }>,
  initialFileOffset: Nullable<{ x: number; y: number }>,
  currentFileOffset: Nullable<{ x: number; y: number }>,
) => {
  if (!initialCursorOffset || !initialFileOffset || !currentFileOffset) {
    return {
      display: 'none',
    };
  }
  const x = initialCursorOffset.x + (currentFileOffset.x - initialFileOffset.x);
  const y = initialCursorOffset.y + (currentFileOffset.y - initialFileOffset.y);
  const transform = `translate(${x}px, ${y}px)`;
  return {
    transform,
    WebkitTransform: transform,
  };
};

export const DnDFileListDragLayer: React.FC<DnDFileListDragLayerProps> = () => {
  const classes = useStyles();

  const { itemType, item, initialCursorOffset, initialFileOffset, currentFileOffset, isDragging } = useDragLayer(
    (monitor) => ({
      item: monitor.getItem() as ChonkyDndFileEntryItem,
      itemType: monitor.getItemType(),
      initialCursorOffset: monitor.getInitialClientOffset(),
      initialFileOffset: monitor.getInitialSourceClientOffset(),
      currentFileOffset: monitor.getSourceClientOffset(),
      isDragging: monitor.isDragging(),
    }),
  );
  if (!isDragging || itemType !== ChonkyDndFileEntryType || !item.payload) {
    return null;
  }

  const selectionSize = item.payload.selectedFiles.length;
  return (
    <div style={layerStyles}>
      <div style={getItemStyles(initialCursorOffset, initialFileOffset, currentFileOffset)}>
        <div className={classes.fileDragPreview}>
          <b>{item.payload.draggedFile.name}</b>
          {selectionSize > 1 && (
            <>
              {' and '}
              <strong>
                {selectionSize - 1} other file
                {selectionSize - 1 !== 1 ? 's' : ''}
              </strong>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

const useStyles = makeGlobalChonkyStyles((theme) => ({
  fileDragPreview: {
    boxShadow: `2px 2px 5px ${theme.palette.divider}`,
    backgroundColor: theme.palette.background.default,
    borderRadius: theme.dragLayer.borderRadius,
    fontSize: theme.fontSizes.rootPrimary,
    color: theme.palette.text.primary,
    padding: theme.dragLayer.padding,
    border: theme.dragLayer.border,
    display: 'inline-block',
  },
}));
