import React, { Fragment, useRef, useEffect, useCallback, useState } from 'react';
import { hexValid } from 'helpers/validators';
import { buildClasses } from 'helpers/utilityHelpers';
import { Percent } from 'components';
import './Progress.css';

const buffer = 4;

const Progress = props => {
  const {
    color,
    bgColor,
    pctColor,
    noPct,
    fixedPct,
    current,
    total,
    className,
    styles,
    ...rest
  } = props;

  const [ pctStyle, setPctStyle ] = useState({
    color: hexValid(pctColor) || '#00000080',
  });

  const progress = +(current) / +(total) * 100;
  const validColor = hexValid(color) || '#0d97ff';
  const validBGColor = hexValid(bgColor) || '#4d5153';
  const widthRef = useRef();
  const barWidth = widthRef.current?.offsetWidth;
  const pctRef = useRef();
  const pctWidth = pctRef.current?.offsetWidth;
  const barStyle = { backgroundColor: validBGColor, ...styles };
  const progressStyle = {
    ...styles,
    width: `calc(100% * ${progress / 100})`,
    backgroundColor: validColor,
  };

  const classes = [
    { condition: className, name: className },
    { condition: noPct, name: 'noPct' },
  ];

  const pctBarPos = useCallback(() => {
    const posX = barWidth >= pctWidth + buffer ? barWidth - pctWidth - buffer : 0;

    setPctStyle({
      ...pctStyle,
      transform: `translateX(${fixedPct ? 0 : posX}px)`,
    });
  }, [ pctStyle, fixedPct, barWidth, pctWidth ]);

  useEffect(() => {
    if (!noPct) {
      const resizeObserver = new ResizeObserver(pctBarPos);
      const elements = [ widthRef.current, pctRef.current ];
      elements.forEach(element => resizeObserver.observe(element));
    }
  }, [ barWidth, pctWidth, noPct, pctBarPos ]);

  return (
    <Fragment>
      <div className={buildClasses(classes, 'progressBar')} style={barStyle} {...rest}>
        <div ref={widthRef} className="progress" style={progressStyle}>
          {!noPct && (
            <div ref={pctRef}>
              <Percent
                className="pct"
                current={current}
                total={total}
                style={pctStyle}
              />
            </div>
          )}
        </div>
      </div>
    </Fragment>
  );
};

export { Progress };