import { FC } from 'react';

import { useModal } from '@material-hu/hooks/useModal';
import UploadFile from '@material-hu/icons/material/UploadFile';
import LinearProgress from '@material-hu/mui/LinearProgress';
import Paper from '@material-hu/mui/Paper';
import Stack from '@material-hu/mui/Stack';
import { useTheme, alpha } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import IconsMenu from '@material-hu/components/deprecated/IconsMenu';

import { insertIf } from 'src/utils/arrayUtils';
import { download, bytesToSize } from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { MAX_SIZE } from './constants';
import EditNameModal from './EditNameModal';
import { FormDropStatus, FormDropValue } from './types';

export type AttachmentItemProps = {
  onRemove?: () => void;
  onRetry?: (drop: FormDropValue) => void;
  onEditName?: () => void;
  onEditNameConfirm?: (name: string) => void;
  onDownload?: () => void;
  disabledRemove?: () => void;
  disabledRetry?: () => void;
  disabledEditName?: () => void;
  disabledDownload?: () => void;
  disabled?: boolean;
  maxSize?: number;
  drop: FormDropValue;
};

export const AttachmentItem: FC<AttachmentItemProps> = props => {
  const {
    onRemove = () => null,
    onRetry = () => null,
    onEditName = () => null,
    onEditNameConfirm = () => null,
    onDownload = () => null,
    disabledDownload = false,
    disabledEditName = false,
    disabledRemove = false,
    disabledRetry = false,
    disabled = false,
    maxSize = MAX_SIZE,
    drop,
  } = props;

  const {
    attachment,
    isLoading = false,
    isError = false,
    isSuccess = false,
    status = FormDropStatus.IDLE,
  } = drop;

  const theme = useTheme();
  const { t } = useLokaliseTranslation('backoffice_only');

  const editNameModal = useModal(
    EditNameModal,
    { fullWidth: true, maxWidth: 'sm' },
    {
      attachment,
      onConfirm: onEditNameConfirm,
    },
  );

  const handleDownload = async () => {
    onDownload();
    if (attachment.url) {
      const blob = await fetch(attachment.url).then(r => r.blob());
      download(blob, attachment.name || '');
    }
  };

  const handleEditName = () => {
    onEditName();
    editNameModal.showModal();
  };

  const handleRemove = () => {
    onRemove();
  };

  const handleRetry = () => {
    onRetry(drop);
  };

  const showDownload = !disabledDownload && isSuccess;
  const showEditName = !disabledEditName && (isSuccess || isLoading);
  const showRemove = !disabledRemove;
  const showRetry = !disabledRetry && isError;

  const menuOptions = [
    ...insertIf(showDownload, {
      onClick: () => handleDownload(),
      label: t('backoffice_only:form_drop_attachments.download'),
    }),
    ...insertIf(showEditName, {
      onClick: handleEditName,
      label: t('backoffice_only:form_drop_attachments.edit_name'),
    }),
    ...insertIf(showRetry, {
      onClick: handleRetry,
      label: t('backoffice_only:form_drop_attachments.retry'),
    }),
    ...insertIf(showRemove, {
      onClick: handleRemove,
      label: t('backoffice_only:form_drop_attachments.remove'),
    }),
  ];

  const showMenu = !disabled;

  return (
    <>
      {editNameModal.modal}
      <Stack
        variant="outlined"
        component={Paper}
        sx={{
          gap: 2,
          p: 2,
          flexDirection: 'row',
        }}
      >
        <Stack
          sx={{
            alignItems: 'center',
            justifyContent: 'center',
            height: '40px',
            width: '40px',
            borderRadius: '50%',
            backgroundColor: alpha(
              isError ? theme.palette.error.main : theme.palette.primary.main,
              0.12,
            ),
          }}
        >
          <UploadFile
            sx={{
              color: isError
                ? theme.palette.error.main
                : theme.palette.primary.main,
            }}
          />
        </Stack>
        <Stack
          sx={{
            flexDirection: 'column',
            width: 'calc(100% - 134px)',
          }}
        >
          <Typography
            variant="subtitle1"
            title={attachment.name || ''}
            sx={{
              maxWidth: '100%',
              whiteSpace: 'nowrap',
              overflow: 'hidden',
              textOverflow: 'ellipsis',
            }}
          >
            {attachment.name}
          </Typography>
          <Typography
            variant="body2"
            color={isError ? theme.palette.error.main : undefined}
          >
            {t('backoffice_only:form_drop_attachments.upload_status', {
              context: status,
              size: attachment.size,
              max: bytesToSize(maxSize),
            })}
          </Typography>
          {isLoading && <LinearProgress sx={{ mt: 1 }} />}
        </Stack>
        {showMenu && <IconsMenu options={menuOptions} />}
      </Stack>
    </>
  );
};

export default AttachmentItem;
