import { forwardRef } from 'react';
import PropTypes from 'prop-types';
import { alpha, styled } from '@mui/material/styles';
import classNames from 'classnames';
import Paper from '@mui/material/Paper';
import Stack from '@mui/material/Stack';
import Divider from '@mui/material/Divider';
import Typography from '@mui/material/Typography';
import { visuallyHidden } from '@mui/utils';
import { useElementSize } from '@custom-react-hooks/use-element-size';
import mergeRefs from 'merge-refs';
import ZoomControls from '../containers/ZoomControls';
import ViewerInfo from '../containers/ViewerInfo';
import ViewerNavigation from '../containers/ViewerNavigation';
import ns from '../config/css-ns';
import { PluginHook } from './PluginHook';

const Root = styled(Paper, { name: 'WindowCanvasNavigationControls', slot: 'root' })(({ theme }) => ({
  alignItems: 'center',
  backgroundColor: alpha(theme.palette.background.paper, 0.5),
  bottom: 0,
  cursor: 'default',
  display: 'flex',
  flexDirection: 'column',
  flexWrap: 'wrap',
  justifyContent: 'center',
  position: 'absolute',
  textAlign: 'center',
  width: '100%',
  zIndex: 50,
}));

/**
 * Represents the viewer controls in the mirador workspace.
 */
export const WindowCanvasNavigationControls = forwardRef(({
  showZoomControls = false, visible = true, windowId, zoomToWorld, ...rest
}, ref) => {
  const [sizeRef, size] = useElementSize();

  const pluginProps = {
    showZoomControls, size, visible, windowId, ...rest,
  };
  /**
   * Determine if canvasNavControls are stacked (based on a hard-coded width)
  */
  const canvasNavControlsAreStacked = (size && size.width && size.width <= 253);

  if (!visible) return (<Typography style={visuallyHidden} component="div"><ViewerInfo windowId={windowId} /></Typography>);

  return (
    <Root
      square
      className={
        classNames(
          ns('canvas-nav'),
          canvasNavControlsAreStacked ? ns('canvas-nav-stacked') : null,
        )
      }
      elevation={0}
      ref={mergeRefs(ref, sizeRef)}
    >
      <Stack
        direction={canvasNavControlsAreStacked ? 'column' : 'row'}
        divider={<Divider orientation={canvasNavControlsAreStacked ? 'horizontal' : 'vertical'} variant="middle" flexItem />}
        spacing={0}
      >
        { showZoomControls && <ZoomControls windowId={windowId} zoomToWorld={zoomToWorld} /> }
        <ViewerNavigation windowId={windowId} />
      </Stack>
      <ViewerInfo windowId={windowId} />

      <PluginHook targetName="WindowCanvasNavigationControls" {...pluginProps} />
    </Root>
  );
});

WindowCanvasNavigationControls.propTypes = {
  showZoomControls: PropTypes.bool,
  visible: PropTypes.bool,
  windowId: PropTypes.string.isRequired,
  zoomToWorld: PropTypes.func.isRequired,
};

WindowCanvasNavigationControls.defaultProps = {
  showZoomControls: false,
  visible: true,
};

WindowCanvasNavigationControls.displayName = 'WindowCanvasNavigationControls';
