import styled from '@emotion/styled';
import { useAnimationFrame } from 'framer-motion';
import { CSSProperties, useCallback, useRef } from 'react';

import {
  encodeTimeFormat,
  encodeTimeFormatWithMilliseconds,
} from '@/utils/utils';

const ReadoutSpan = styled.span`
  display: inline-block;
  min-width: 34px;
  text-align: left;
`;

export default function TimeReadout({
  getCurrentTime,
  songEndSeconds,
  className,
  style,
  timeDisplayStyle = 'second',
  leftAlign = false,
}: {
  getCurrentTime: () => number;
  songEndSeconds: number | undefined;
  className?: string;
  style?: CSSProperties;
  timeDisplayStyle?: 'second' | 'millisecond';
  leftAlign?: boolean;
}) {
  const currentTimeRef = useRef<HTMLSpanElement>(null);
  const durationRef = useRef<HTMLSpanElement>(null);
  useAnimationFrame(
    useCallback(() => {
      const currentTime = getCurrentTime();
      let currentTimeStr;
      if (timeDisplayStyle === 'millisecond') {
        currentTimeStr =
          encodeTimeFormatWithMilliseconds(currentTime) || '0:00.000';
      } else {
        currentTimeStr = encodeTimeFormat(currentTime) || '0:00';
      }

      if (
        currentTimeRef.current &&
        currentTimeRef.current.textContent !== currentTimeStr
      ) {
        currentTimeRef.current.textContent = currentTimeStr;
      }

      let durationStr;
      if (timeDisplayStyle === 'millisecond') {
        durationStr = ''; // Don't show duration in milliseconds
      } else {
        durationStr =
          songEndSeconds === undefined
            ? '-:--'
            : encodeTimeFormat(songEndSeconds) || '0:00';
      }

      if (
        durationRef.current &&
        durationRef.current.textContent !== durationStr
      ) {
        durationRef.current.textContent = durationStr;
      }
    }, [songEndSeconds, timeDisplayStyle, getCurrentTime])
  );
  return (
    <span className={className} style={style}>
      <ReadoutSpan
        ref={currentTimeRef}
        style={{
          textAlign: leftAlign ? 'left' : 'right',
          marginRight: 2,
          minWidth: leftAlign ? 0 : '',
        }}
      />
      {timeDisplayStyle === 'second' && (
        <>
          <span>/</span>
          <ReadoutSpan ref={durationRef} style={{ marginLeft: 2 }} />
        </>
      )}
    </span>
  );
}
