import React, { useEffect, useMemo, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { OpenInFull } from '@mui/icons-material';

import { getNumberInRange } from '@/modules/@common/helpers/number';

import FormPreview from '@/modules/forms/common/components/FormPreview';
import {
  Autocomplete,
  Button,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  InputAdornment,
  Stack,
  TextField,
} from '@/mui/components';

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

const MIN_WIDTH = 320;
const DEFAULT_WIDTH = 512;

function PlayerPreview(props) {
  const wrapperRef = useRef(null);
  const resizableContainerRef = useRef(null);

  // eslint-disable-next-line react/prop-types
  const [player, setPlayer] = useState(props.playerOptions[0]);
  const [widthRatio, heightRatio] = useMemo(
    () => player.playerAspectRatio.split(/[:_-]/).map(Number),
    [player.playerAspectRatio],
  );
  const [width, setWidth] = useState(DEFAULT_WIDTH);
  const [height, setHeight] = useState(width / (widthRatio / heightRatio));

  const setupDimensions = (widthSource) => {
    const newWidth = Math.round(
      getNumberInRange(widthSource, MIN_WIDTH, wrapperRef.current?.clientWidth || Number.MAX_SAFE_INTEGER),
    );

    setWidth(newWidth);
    setHeight(Math.round(newWidth / (widthRatio / heightRatio)));
  };

  useEffect(() => {
    const timer = setTimeout(() => setupDimensions(+width), 1000);

    return () => {
      clearTimeout(timer);
    };
  }, [width]);

  const resize = (e) => {
    e.preventDefault();
    const newWidth = e.clientX - resizableContainerRef.current.getBoundingClientRect().left;
    setupDimensions(newWidth);
  };

  const stopResize = () => {
    document.removeEventListener('mousemove', resize);
    document.removeEventListener('mouseup', stopResize);
    document.removeEventListener('mouseleave', stopResize);
  };

  const startResize = (e) => {
    e.preventDefault();
    document.addEventListener('mousemove', resize);
    document.addEventListener('mouseup', stopResize);
    document.addEventListener('mouseleave', stopResize);
  };

  return (
    <Dialog fullScreen open onClose={props.onClose}>
      <DialogTitle onClose={props.onClose}>Player Inline View</DialogTitle>
      <DialogContent ref={wrapperRef}>
        <Stack spacing={3} alignItems="center">
          <div className={styles.FormRow}>
            <div className={styles.FormLabel}>Select Player</div>
            <Stack fullWidth direction="row" spacing={2} alignItems="center">
              <Autocomplete
                fullWidth
                disableClearable
                getOptionLabel={(option) => {
                  if (option.playerAspectRatio) {
                    return `${option.label}_${option.playerAspectRatio.replace('_', ':')}`;
                  }
                  return option.label || '';
                }}
                size="small"
                renderInput={(params) => (
                  <TextField
                    {...params}
                    data-id="player-name-input"
                    value=""
                    variant="outlined"
                    placeholder="Select Player"
                  />
                )}
                // eslint-disable-next-line react/prop-types
                options={props.playerOptions}
                onChange={(e, selectedPlayer) => setPlayer(selectedPlayer)}
                value={player}
              />
              <TextField
                size="small"
                value={player.playerAspectRatio.replace('_', ':')}
                variant="outlined"
                placeholder="Ratio"
                label="Ratio"
                inputProps={{
                  readOnly: true,
                }}
              />
            </Stack>
          </div>
          <div className={styles.FormRow}>
            <div className={styles.FormLabel}>Set Player Size</div>
            <Stack fullWidth direction="row" spacing={2} alignItems="center">
              <TextField
                size="small"
                type="number"
                value={width}
                variant="outlined"
                placeholder=""
                label=""
                inputProps={{
                  min: MIN_WIDTH,
                }}
                InputProps={{
                  startAdornment: (
                    <InputAdornment position="start">
                      <Chip variant="text" size="small" color="neutral" label="W" />
                    </InputAdornment>
                  ),
                }}
                onChange={({ target }) => setWidth(target.value)}
              />
              <TextField
                size="small"
                type="number"
                value={height}
                variant="outlined"
                placeholder=""
                label=""
                InputProps={{
                  startAdornment: (
                    <InputAdornment position="start">
                      <Chip variant="text" size="small" color="neutral" label="H" />
                    </InputAdornment>
                  ),
                }}
                onChange={({ target }) => {
                  setWidth(Math.round(+target.value / (heightRatio / widthRatio)));
                  setHeight(target.value);
                }}
              />
            </Stack>
          </div>
          <Stack alignItems="center" fullWidth>
            <div
              ref={resizableContainerRef}
              className={styles.ResizableContainer}
              style={{
                width: Math.max(width, MIN_WIDTH),
                height: Math.max(width, MIN_WIDTH) / (widthRatio / heightRatio),
              }}
            >
              <div className={styles.FormPreview}>
                <FormPreview metadata={props.metadata} />
              </div>
              <IconButton size="xSmall" onMouseDown={startResize} className={styles.ResizeHandle}>
                <OpenInFull />
              </IconButton>
            </div>
          </Stack>
        </Stack>
      </DialogContent>
      <DialogActions>
        <Button size="small" variant="contained" color="primary" onClick={props.onClose}>
          Close
        </Button>
      </DialogActions>
    </Dialog>
  );
}

PlayerPreview.propTypes = {
  metadata: PropTypes.shape({}).isRequired,
  onClose: PropTypes.func.isRequired,
};

export default PlayerPreview;
