// @flow
import React from 'react';
import { useDropzone } from 'react-dropzone';
import styled from 'styled-components';
import { Box } from '../../primitives/box';
import { UnstyledButton } from '../../core/behaviors/unstyled-button';
import { Text } from '../../core/typography/text';
import { Remove } from '../../core/icon/remove';
import { Checkmark } from '../../core/icon/checkmark';
import type { FileUploaderProps } from './file-uploader.proptypes';
import {
  getDropzoneHeight,
  getDropzoneBorderColor,
} from './file-uploader.css-rules';
import { TextButtonWithIcon } from '../../core/actions/text-button-with-icon';
import { LoadingIndicator } from '../../core/feedback-ui/loading-indicator';

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

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

StyledDropzoneContainer.displayName = 'StyledDropzoneContainer';

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

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}`;

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';

export const FileUploader = (props: FileUploaderProps) => {
  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 (
    <Box data-cy={props['data-cy']} data-qa={props['data-qa']} id={props.id}>
      <StyledDropzoneContainer
        {...getRootProps()}
        attachments={props.attachments}
        attachmentsError={props.attachmentsError}
        baseHeight={props.baseHeight}
        savePending={props.savePending}
        isDragActive={isDragActive}
        className={props.className}
      >
        <StyledDiv style={{ border: 'none', width: '100%' }}>
          <input
            {...getInputProps()}
            label={
              hasAttachments ? props.withFilesPrompt : props.withoutFilesPrompt
            }
          />
          {!hasAttachments && (
            <WithoutFilesDropzoneChild>
              <TextButtonWithIcon
                onClick={open}
                spacing="mb2"
                icon="add"
                position="left"
              >
                {props.withoutFilesPrompt}
              </TextButtonWithIcon>

              <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>
              <LoadingIndicator
                ready={!props.savePending}
                minHeight="30px"
                spacing="mv2"
              >
                <Box stacked="row" justify="center">
                  <TextButtonWithIcon onClick={open} icon="add" position="left">
                    {props.withFilesPrompt}
                  </TextButtonWithIcon>
                </Box>
              </LoadingIndicator>
            </WithFilesDropzoneChild>
          )}
        </StyledDiv>
      </StyledDropzoneContainer>
      {hasErrors && (
        <Box spacing={['mv1']}>
          <CenteredText colorName="error-fg">
            {props.attachmentsError}
          </CenteredText>
        </Box>
      )}
    </Box>
  );
};

FileUploader.displayName = 'FileUploader';
