import { useAnimationFrame } from 'framer-motion';
import { useRef } from 'react';

import { useContextSelector } from '@/hooks/useContextSelector';
import modulo from '@/utils/modulo';
import { encodeTimeFormat } from '@/utils/utils';

import StudioContext from './StudioContext';

export const CurrentBeats = ({ suspend }: { suspend?: boolean }) => {
  const beatsRef = useRef<HTMLSpanElement>(null);
  const lastBeatsRef = useRef('');
  const getCurrentBeats = useContextSelector(
    StudioContext,
    (ctx) => ctx.playbackController.getCurrentBeats
  );
  useAnimationFrame(() => {
    if (!beatsRef.current || suspend) return;
    const totalBeats = getCurrentBeats();
    const bars = Math.floor(totalBeats / 4);
    const beats = Math.floor(modulo(totalBeats, 4));
    const sixteenths = Math.floor(modulo(totalBeats * 4, 4));
    const beatsStr = `${(bars + 1).toString().padStart(3, '0')}.${(beats + 1).toString().padStart(1, '0')}.${(sixteenths + 1).toString().padStart(1, '0')}`;
    if (beatsStr !== lastBeatsRef.current) {
      lastBeatsRef.current = beatsStr;
      beatsRef.current.textContent = beatsStr;
    }
  });
  return (
    <span ref={beatsRef}>{suspend ? '000.0.0' : lastBeatsRef.current}</span>
  );
};

export const CurrentSeconds = ({ suspend }: { suspend?: boolean }) => {
  const secondsRef = useRef<HTMLSpanElement>(null);
  const lastSecondsRef = useRef('');
  const getCurrentSeconds = useContextSelector(
    StudioContext,
    (ctx) => ctx.playbackController.getCurrentSeconds
  );
  useAnimationFrame(() => {
    if (!secondsRef.current || suspend) return;
    const secondsStr = encodeTimeFormat(getCurrentSeconds(), 3) ?? '';
    if (secondsStr !== lastSecondsRef.current) {
      lastSecondsRef.current = secondsStr;
      secondsRef.current.textContent = secondsStr;
    }
  });
  return (
    <span ref={secondsRef}>
      {suspend ? '00:00.000' : lastSecondsRef.current}
    </span>
  );
};
