// @flow
import React from 'react';
import type { ComponentType } from 'react';
import { useDropzone } from 'react-dropzone';
import styled, { withTheme } from 'styled-components';
import { Box } from '../../primitives/box';
import { UnstyledButton } from '../../core/behaviors/unstyled-button';
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 {
  getDropzoneHeight,
  getDropzoneOpacity,
  getDropzoneBorderColor,
} from './file-uploader.css-rules';
import type { ThemeProps } from '../../types';

const StyledDropzoneContainer = styled.div`
  border-color: ${getDropzoneBorderColor};
  border-radius: 5px;
  border-style: dashed;
  border-width: 2px;
  height: ${getDropzoneHeight};
  opacity: ${getDropzoneOpacity};
  width: 100%;
  display: flex;
  justify-content: center;
`;

const StyledDiv = styled.div`
  border: none;
  width: 100%;
`;

StyledDropzoneContainer.displayName = 'StyledDropzoneContainer';

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

const RemoveBox = styled(Box)`
  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 CenteredText = styled(Text)`
  text-align: center;
`;

const removeLabel = (fileName: string) => `Remove ${fileName}`;

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 |}) => {
  const hasAttachments = props.attachments && props.attachments.length > 0;
  const hasErrors = !!props.attachmentsError;
  const { getRootProps, getInputProps, isDragActive, open } = useDropzone({
    onDrop: props.onDropAttachmentHandler,
    accept: props.acceptedFileTypes,
    noClick: true,
  });

  return (
    <div>
      <StyledDropzoneContainer
        {...getRootProps()}
        attachments={props.attachments}
        attachmentsError={props.attachmentsError}
        savePending={props.savePending}
        isDragActive={isDragActive}
        theme={props.theme}
      >
        <StyledDiv style={{ border: 'none', width: '100%' }}>
          <input
            {...getInputProps()}
            label={
              hasAttachments ? props.withFilesPrompt : props.withoutFilesPrompt
            }
          />
          {!hasAttachments && (
            <WithoutFilesDropzoneChild>
              <UnstyledButton onClick={open}>
                <IconTextBox spacing="mb2">
                  <FullSizeAdd />
                  <Text
                    colorName="brand-primary-base"
                    spacing={['mv0', 'mr0', 'ml1']}
                    bold
                  >
                    {props.withoutFilesPrompt}
                  </Text>
                </IconTextBox>
              </UnstyledButton>

              <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 spacing="mr2">
                      <UnstyledButton
                        onClick={() => {
                          if (!props.savePending) props.onClickRemoveHandler(f);
                        }}
                        aria-label={removeLabel(f.name)}
                      >
                        <Remove />
                      </UnstyledButton>
                    </RemoveBox>
                  </Box>
                ))}
              </FullWidthBox>
              <UnstyledButton
                onClick={() => {
                  if (!props.savePending) open();
                }}
              >
                <IconTextBox spacing="mv2">
                  <FullSizeAdd />
                  <Text
                    colorName="brand-primary-base"
                    spacing={['mv0', 'ml1']}
                    bold
                  >
                    {props.withFilesPrompt}
                  </Text>
                </IconTextBox>
              </UnstyledButton>
            </WithFilesDropzoneChild>
          )}
        </StyledDiv>
      </StyledDropzoneContainer>
      {hasErrors && (
        <Box spacing={['mv1']}>
          <CenteredText colorName="error-fg">
            {props.attachmentsError}
          </CenteredText>
        </Box>
      )}
    </div>
  );
};

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