import {
  addSecondsToBeats,
  getSecondsBetween,
} from '@suno/studiokit/timeMapping';

import {
  getDerivedTiming,
  getStudioClipsById,
  getStudioClipsByTrackId,
  getUnwarpedStudioClips,
} from '../selectors';
import { StudioProjectState } from '../types';
import updateClips from './updateClips';

export default function retimeUnwarpedClips(oldState: StudioProjectState) {
  return (newState: StudioProjectState): StudioProjectState => {
    const unwarpedClips = getUnwarpedStudioClips(newState);
    const clipIdsOnTempoTrack =
      newState.timing.type === 'manual'
        ? []
        : (getStudioClipsByTrackId(newState)[newState.timing.trackId]?.map(
            (c) => c.id
          ) ?? []);
    return updateClips(
      unwarpedClips
        .map((c) => c.id)
        .filter((id) => !clipIdsOnTempoTrack.includes(id)),
      (newClip) => {
        const oldClip = getStudioClipsById(oldState)[newClip.id];
        if (!oldClip) return newClip;

        const oldDurationSeconds = getSecondsBetween(
          oldClip.startBeats,
          oldClip.startBeats + (newClip.endBeats - newClip.startBeats),
          getDerivedTiming(oldState)
        );

        const newEndBeats = addSecondsToBeats(
          oldDurationSeconds,
          newClip.startBeats,
          getDerivedTiming(newState)
        );

        return {
          ...newClip,
          endBeats: newEndBeats,
        };
      }
    )(newState);
  };
}
