import React, { useEffect, useRef } from 'react';
import Draggable from 'react-draggable';
import styled, { css } from 'styled-components';
import { uiFonts } from '../constants/uiFonts';
import { useOutsideClick } from '../hooks/useOutsideAlerter';
import { IPosition } from '../types/eventTypes';
import { RPGUIContainerTypes } from './RPGUI/RPGUIContainer';

export interface IDraggableContainerProps {
  children: React.ReactNode;
  width?: string;
  height?: string;
  minWidth?: string;
  minHeight?: string;
  className?: string;
  type?: RPGUIContainerTypes;
  title?: string;
  imgSrc?: string;
  imgWidth?: string;
  onCloseButton?: () => void;
  cancelDrag?: string;
  onPositionChange?: (position: IPosition) => void;
  onPositionChangeEnd?: (position: IPosition) => void;
  onPositionChangeStart?: (position: IPosition) => void;
  onOutsideClick?: () => void;
  initialPosition?: IPosition;
  scale?: number;
  dragDisabled?: boolean;
  isFullScreen?: boolean;
  opacity?: number;
}

export const DraggableContainer: React.FC<IDraggableContainerProps> = ({
  children,
  width = '50%',
  height,
  minHeight,
  minWidth,
  className,
  type = RPGUIContainerTypes.FramedGold,
  onCloseButton,
  title,
  imgSrc,
  imgWidth = '20px',
  cancelDrag,
  onPositionChange,
  onPositionChangeEnd,
  onPositionChangeStart,
  onOutsideClick,
  initialPosition = { x: 0, y: 0 },
  scale,
  dragDisabled = false,
  isFullScreen,
  opacity,
}) => {
  const draggableRef = useRef(null);

  if (isFullScreen) {
    width = '100%';
    height = '100%';
  }

  useOutsideClick(draggableRef, 'item-container');

  useEffect(() => {
    document.addEventListener('clickOutside', event => {
      const e = event as CustomEvent;

      if (e.detail.id === 'item-container') {
        if (onOutsideClick) {
          onOutsideClick();
        }
      }
    });

    return () => {
      document.removeEventListener('clickOutside', _e => {});
    };
  }, []);

  return (
    <Draggable
      cancel={`.container-close,input,button,${cancelDrag}`}
      disabled={dragDisabled}
      onDrag={(_e, data) => {
        if (onPositionChange) {
          onPositionChange({
            x: data.x,
            y: data.y,
          });
        }
      }}
      onStop={(_e, data) => {
        if (onPositionChangeEnd) {
          onPositionChangeEnd({
            x: data.x,
            y: data.y,
          });
        }
      }}
      onStart={(_e, data) => {
        if (onPositionChangeStart) {
          onPositionChangeStart({
            x: data.x,
            y: data.y,
          });
        }
      }}
      defaultPosition={initialPosition}
      scale={scale}
    >
      <Container
        ref={draggableRef}
        width={width}
        height={height || 'auto'}
        minWidth={minWidth}
        minHeight={minHeight}
        className={`rpgui-container ${type} ${className}`}
        isFullScreen={isFullScreen}
        opacity={opacity}
      >
        {title && (
          <TitleContainer className="drag-handler">
            <Title>
              {imgSrc && <Icon src={imgSrc} width={imgWidth} />}
              {title}
            </Title>
          </TitleContainer>
        )}
        {onCloseButton && (
          <CloseButton
            className="container-close"
            onPointerDown={onCloseButton}
          >
            X
          </CloseButton>
        )}

        {children}
      </Container>
    </Draggable>
  );
};

interface IContainerProps {
  width: string;
  height: string;
  minWidth?: string;
  minHeight?: string;
  isFullScreen?: boolean;
  opacity?: number;
}

const Container = styled.div<IContainerProps>`
  height: ${props => props.height};
  width: ${({ width }) => width};
  min-width: ${({ minWidth }) => minWidth || 'auto'};
  min-height: ${({ minHeight }) => minHeight || 'auto'};
  display: flex;
  flex-wrap: wrap;
  image-rendering: pixelated;

  overflow-y: hidden;

  ${({ opacity }) =>
    opacity &&
    css`
      opacity: ${opacity};
    `}

  ${({ isFullScreen }) =>
    isFullScreen &&
    css`
      justify-content: center;
      align-items: flex-start;
      align-content: flex-start;
    `}

  &.rpgui-container {
    padding-top: 1.5rem;
  }
`;

const CloseButton = styled.div`
  position: absolute;
  top: 3px;
  right: 0px;
  color: white;
  z-index: 22;
  font-size: 1.5rem;
  @media (max-width: 950px) {
    font-size: 1.7rem;
    padding: 12px;
  }
`;

const TitleContainer = styled.div`
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  max-height: 42px;
`;

const Title = styled.h1`
  color: white;
  z-index: 22;
  font-size: ${uiFonts.size.large};
`;

interface ICustomIconProps {
  width: string;
}

const Icon = styled.img<ICustomIconProps>`
  color: white;
  z-index: 22;
  font-size: ${uiFonts.size.xsmall};
  width: ${({ width }) => width};
  margin-right: 0.5rem;
`;
