import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useRouter } from 'next/router';
import { CheckOutlined, CloseOutlined, NotInterestedOutlined, SyncOutlined } from '@mui/icons-material';

import { EDITORIAL_PAGE } from '@/modules/@common/router/constants';
import {
  CANCEL_ALL_UPLOAD_TEXT_BODY,
  CANCEL_ALL_UPLOAD_TEXT_CANCEL_BUTTON,
  CANCEL_ALL_UPLOAD_TEXT_CONFIRM_BUTTON,
  CANCEL_ALL_UPLOAD_TEXT_TITLE,
  CANCEL_ITEM_UPLOAD_TEXT_BODY,
  CANCEL_ITEM_UPLOAD_TEXT_CANCEL_BUTTON,
  CANCEL_ITEM_UPLOAD_TEXT_CONFIRM_BUTTON,
  CANCEL_ITEM_UPLOAD_TEXT_TITLE,
  CANCEL_UPLOAD_PROGRESS_UPLOAD,
  UPLOAD_STATUS_CANCELED,
  UPLOAD_STATUS_COMPLETE,
  UPLOAD_STATUS_FAILED,
  UPLOAD_STATUS_UPLOADING,
  UPLOAD_STATUS_WAIT,
} from '@/modules/uploaderNew/constants';

import { queueSelector, uploadConfirmDialogSelector } from '../../redux/selectors';
import {
  clearUploadQueueAction,
  handleCancelUploadFromConfirmDialogAction,
  hideCancelUploadConfirmDialogAction,
  isOpenAction,
  showCancelUploadConfirmDialogAction,
} from '../../redux/slices';
import {
  getFilesProcessingStatuses,
  getHeaderText,
  toMb,
  toPercentage,
  toPercentageWithSign,
  toTitle,
} from './helpers';
import { getSessionStorageItem, setSessionStorageItem } from '@/modules/@common/storage/helpers';

import Container from '@/modules/layout/components/FloatBlock/components/Container/Container';
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Grid,
  LinearProgress,
  Stack,
  Typography,
} from '@/mui/components';

import styles from './MultiUploadStatusDialog.module.scss';

const SHOULD_OPEN_UPLOAD_DIALOG = 'soud';

function MultiUploadStatusDialog(props) {
  const dispatch = useDispatch();
  const router = useRouter();

  const queue = useSelector(queueSelector);
  const uploadConfirmDialog = useSelector(uploadConfirmDialogSelector);

  const shouldOpenUploadDialog = getSessionStorageItem(SHOULD_OPEN_UPLOAD_DIALOG) === 'true';

  const { hasInProgress } = getFilesProcessingStatuses(queue);
  const files = Object.keys(queue).reverse();

  const handleCancelUploadAllDialog = () => {
    dispatch(
      showCancelUploadConfirmDialogAction({
        title: CANCEL_ALL_UPLOAD_TEXT_TITLE,
        body: CANCEL_ALL_UPLOAD_TEXT_BODY,
        cancelButtonText: CANCEL_ALL_UPLOAD_TEXT_CANCEL_BUTTON,
        confirmButtonText: CANCEL_ALL_UPLOAD_TEXT_CONFIRM_BUTTON,
        context: CANCEL_UPLOAD_PROGRESS_UPLOAD,
      }),
    );
  };
  const handleCancelUploadDialog = ({ fileName, processedUploadQueueId }) => {
    dispatch(
      showCancelUploadConfirmDialogAction({
        title: CANCEL_ITEM_UPLOAD_TEXT_TITLE,
        body: CANCEL_ITEM_UPLOAD_TEXT_BODY.replace('{name}', fileName),
        cancelButtonText: CANCEL_ITEM_UPLOAD_TEXT_CANCEL_BUTTON,
        confirmButtonText: CANCEL_ITEM_UPLOAD_TEXT_CONFIRM_BUTTON,
        processedUploadQueueId,
        context: CANCEL_UPLOAD_PROGRESS_UPLOAD,
      }),
    );
  };

  const handleCancelAllUpload = () => dispatch(clearUploadQueueAction());

  const handleTryUpload = () => {
    if (router.pathname === EDITORIAL_PAGE.path) {
      dispatch(isOpenAction(true));
    } else {
      setSessionStorageItem(SHOULD_OPEN_UPLOAD_DIALOG, 'true');
      router.push(EDITORIAL_PAGE.path);
    }
  };

  // Open upload dialog when user click to 'Try Again'
  useEffect(() => {
    if (shouldOpenUploadDialog) {
      dispatch(isOpenAction(true));
    }
  }, [shouldOpenUploadDialog]);

  return files.length !== 0 ? (
    <Container
      title={getHeaderText(queue)}
      headerWithoutRadius={props.headerWithoutRadius}
      onClose={() => (hasInProgress ? handleCancelUploadAllDialog() : handleCancelAllUpload())}
    >
      <Grid container className={styles.Body}>
        {files.map((processedUploadQueueId) => {
          const qItem = queue[processedUploadQueueId];
          return (
            <Grid key={processedUploadQueueId} container className={styles.File}>
              <Grid container justifyContent="space-between">
                <Grid item className={styles.FileName} title={qItem.title}>
                  <Typography variant="body2" color="text.primary">
                    {qItem.csvFile ? 'Upload video form CSV' : toTitle(qItem.title)}
                  </Typography>
                </Grid>
                <Grid item>
                  <Typography variant="caption" color="text.primary">
                    {toMb(qItem.video?.size)}
                  </Typography>
                </Grid>
              </Grid>
              <Grid container>
                <LinearProgress
                  variant="determinate"
                  value={toPercentage(qItem.loadingProgress)}
                  color="info"
                  className={styles.FileProgressBarControl}
                />
              </Grid>
              <Grid
                container
                justifyContent="space-between"
                alignItems="center"
                className={styles.FileBottomAttributes}
              >
                <Grid item>
                  {qItem.processedUploadStatus !== UPLOAD_STATUS_CANCELED &&
                    qItem.processedUploadStatus !== UPLOAD_STATUS_FAILED && (
                      <Typography variant="caption" color="text.primary">
                        {toPercentageWithSign(qItem.loadingProgress)}
                      </Typography>
                    )}

                  {qItem.processedUploadStatus === UPLOAD_STATUS_FAILED && (
                    <Typography variant="caption" color="error.main">
                      Upload failed
                    </Typography>
                  )}
                </Grid>
                <Grid item>
                  {(qItem.processedUploadStatus === UPLOAD_STATUS_UPLOADING ||
                    qItem.processedUploadStatus === UPLOAD_STATUS_WAIT) && (
                    <Button
                      variant="text"
                      size="xSmall"
                      color="neutral"
                      onClick={() =>
                        handleCancelUploadDialog({
                          fileName: qItem.title,
                          processedUploadQueueId,
                        })
                      }
                      startIcon={<CloseOutlined />}
                      style={{
                        // @todo Remove sx after PCN moved to new uikit
                        // eslint-disable-next-line local-rules/no-inline-styles
                        fontSize: '12px !important',
                        // eslint-disable-next-line local-rules/no-inline-styles
                        borderRadius: '4px !important',
                      }}
                    >
                      Cancel upload
                    </Button>
                  )}
                  {qItem.processedUploadStatus === UPLOAD_STATUS_COMPLETE && (
                    <Stack direction="row" alignItems="center" gap={1}>
                      <Typography variant="caption" color="text.primary">
                        Complete
                      </Typography>
                      <CheckOutlined htmlColor="success.main" fontSize="xSmall" />
                    </Stack>
                  )}
                  {qItem.processedUploadStatus === UPLOAD_STATUS_CANCELED && (
                    <Stack direction="row" alignItems="center" gap={1}>
                      <Typography variant="caption" color="text.primary">
                        Video upload cancelled
                      </Typography>
                      <NotInterestedOutlined htmlColor="error.main" fontSize="xSmall" />
                    </Stack>
                  )}
                  {qItem.processedUploadStatus === UPLOAD_STATUS_FAILED && (
                    <Button
                      variant="text"
                      size="xSmall"
                      color="neutral"
                      onClick={handleTryUpload}
                      startIcon={<SyncOutlined />}
                      style={{
                        // @todo Remove sx after PCN moved to new uikit
                        // eslint-disable-next-line local-rules/no-inline-styles
                        fontSize: '12px !important',
                        // eslint-disable-next-line local-rules/no-inline-styles
                        borderRadius: '4px !important',
                      }}
                    >
                      Try again
                    </Button>
                  )}
                </Grid>
              </Grid>
            </Grid>
          );
        })}
      </Grid>

      {!!uploadConfirmDialog && (
        <Dialog
          open={!!uploadConfirmDialog}
          onClose={() => dispatch(hideCancelUploadConfirmDialogAction())}
          maxWidth="sm"
        >
          <DialogTitle onClose={() => dispatch(hideCancelUploadConfirmDialogAction())}>
            {uploadConfirmDialog?.title}
          </DialogTitle>
          <DialogContent className={styles.DialogContent}>{uploadConfirmDialog?.body}</DialogContent>
          <DialogActions>
            <Button
              size="small"
              variant="outlined"
              color="primary"
              onClick={() => dispatch(handleCancelUploadFromConfirmDialogAction())}
            >
              {uploadConfirmDialog?.cancelButtonText}
            </Button>
            <Button
              size="small"
              variant="contained"
              color="primary"
              onClick={() => dispatch(hideCancelUploadConfirmDialogAction())}
            >
              {uploadConfirmDialog?.confirmButtonText}
            </Button>
          </DialogActions>
        </Dialog>
      )}
    </Container>
  ) : null;
}

MultiUploadStatusDialog.propTypes = {
  headerWithoutRadius: PropTypes.bool,
};

export default MultiUploadStatusDialog;
