// @flow
import React from 'react';
import type { ComponentType } from 'react';
import Dropzone from 'react-dropzone';
import styled, { withTheme } from 'styled-components';
import { Box } from '../../primitives/box';
import { Text } from '../../core/typography/text';
import { Add } from '../../core/icon/add';
import { Remove } from '../../core/icon/remove';
import { Checkmark } from '../../core/icon/checkmark';
import type { FileUploaderProps } from './file-uploader.proptypes';
import { fileUploaderPropTypes } from './file-uploader.proptypes';
import {
  getDropzoneHeight,
  getDropzoneOpacity,
  getDropzoneBorderColor,
} from './file-uploader.css-rules';
import type { ThemeProps } from '../../types';

const StyledDropzone = styled(Dropzone)`
  border: none;
  width: 100%;
`;

const StyledDropzoneContainer = styled(Box)`
  border-color: ${getDropzoneBorderColor};
  border-radius: 5px;
  border-style: dashed;
  border-width: 2px;
  height: ${getDropzoneHeight};
  opacity: ${getDropzoneOpacity};
  width: 100%;
`;

StyledDropzoneContainer.displayName = 'StyledDropzoneContainer';

const FullSizeAdd = styled(Add)`
  height: 100%;
`;

const RemoveBox = styled(Box)`
  cursor: pointer;
  margin-left: auto;
`;

const IconTextBox = styled(Box)`
  align-items: center;
  display: flex;
  flex-direction: row;
  justify-content: center;
`;

const FullWidthBox = styled(Box)`
  width: 100%;
`;

const StyledTextTip = styled(Text)`
  max-width: 240px;
  text-align: center;
`;

const ClickableText = styled(Text)`
  cursor: pointer;
`;

const CenteredText = styled(Text)`
  text-align: center;
`;

IconTextBox.displayName = 'IconTextBox';

const WithoutFilesDropzoneChild = styled(Box)`
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100%;
  justify-content: center;
`;
WithoutFilesDropzoneChild.displayName = 'WithoutFilesDropzoneChild';
const WithFilesDropzoneChild = styled(Box)`
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100%;
`;
WithFilesDropzoneChild.displayName = 'WithFilesDropzoneChild';

const _FileUploader = (props: FileUploaderProps & ThemeProps) => {
  let dropzoneRef;
  const hasAttachments = props.attachments && props.attachments.length > 0;
  const hasErrors = !!props.attachmentsError;
  return (
    <StyledDropzoneContainer
      attachments={props.attachments}
      attachmentsError={props.attachmentsError}
      savePending={props.savePending}
      theme={props.theme}
      stacked="row"
    >
      <StyledDropzone
        onDrop={props.onDropAttachmentHandler}
        accept={props.acceptedFileTypes}
        disableClick
        ref={node => {
          dropzoneRef = node;
        }}
      >
        {!hasAttachments && (
          <WithoutFilesDropzoneChild>
            <IconTextBox spacing="mb2">
              <FullSizeAdd />
              <ClickableText
                colorName="brand-primary-base"
                spacing={['mv0', 'mr0', 'ml1']}
                onClick={() => dropzoneRef && dropzoneRef.open()}
                bold
              >
                {props.withoutFilesPrompt}
              </ClickableText>
            </IconTextBox>
            <StyledTextTip spacing="m0" fontSize="f1">
              {props.tip}
            </StyledTextTip>
          </WithoutFilesDropzoneChild>
        )}
        {hasAttachments && (
          <WithFilesDropzoneChild>
            <FullWidthBox spacing="mt1">
              {props.attachments.map(f => (
                <Box
                  stacked="row"
                  align="center"
                  spacing={['mt1', 'ml2']}
                  key={f.name}
                >
                  <Checkmark />
                  <Text spacing={['mv0', 'ml2']}>{f.name}</Text>
                  <RemoveBox
                    onClick={() =>
                      !props.savePending && props.onClickRemoveHandler(f)
                    }
                    spacing="mr2"
                  >
                    <Remove />
                  </RemoveBox>
                </Box>
              ))}
            </FullWidthBox>
            <IconTextBox spacing="mv2">
              <FullSizeAdd />
              <ClickableText
                colorName="brand-primary-base"
                spacing={['mv0', 'ml1']}
                onClick={() =>
                  !props.savePending && dropzoneRef && dropzoneRef.open()
                }
                bold
              >
                {props.withFilesPrompt}
              </ClickableText>
            </IconTextBox>
          </WithFilesDropzoneChild>
        )}
        {hasErrors && (
          <Box spacing={['mv1']}>
            <CenteredText colorName="error-fg">
              {props.attachmentsError}
            </CenteredText>
          </Box>
        )}
      </StyledDropzone>
    </StyledDropzoneContainer>
  );
};

export const FileUploader: ComponentType<FileUploaderProps> = withTheme(
  _FileUploader,
);
FileUploader.displayName = 'FileUploader';
FileUploader.propTypes = fileUploaderPropTypes;
