import { v4 as uuidv4 } from 'uuid';

import insertClipCreationIntentsToList from '../insertClipCreationIntentsToList';
import { ClipCreationIntent, StudioProjectState } from '../types';
import { isValidClipCreationIntent } from './updateClipCreationIntents';

/**
 * Creates a state updater function that updates specific clip creation intents within tracks.
 * This is a common pattern used throughout the codebase to update clip creation intent properties.
 *
 * @param clipCreationIntentIds The IDs of the clip creation intents to update
 * @param updateFn A function that receives the current clip creation intent and returns the updated clip creation intent
 * @returns A function that can be used with setState to update the clip creation intents
 */

export default function duplicateClipCreationIntents(
  clipCreationIntentIds: string[],
  updateFn: (clipCreationIntent: ClipCreationIntent) => ClipCreationIntent
) {
  return (state: StudioProjectState): StudioProjectState => ({
    ...state,
    metadata: {
      ...state.metadata,
      usedDuplicate: true,
    },
    tracks: state.tracks.map((track) => {
      const clipCreationIntents = track.clipCreationIntents.filter((c) =>
        clipCreationIntentIds.includes(c.id)
      );
      if (!clipCreationIntents.length) return track;
      return {
        ...track,
        clipCreationIntents: insertClipCreationIntentsToList(
          // the ID is not overwritten here - the updated clip by default behaves as though it is the original clip.
          // since the manipulated copy is likely the one that has the user's attention, we probably want it to retain any selection and focus references.
          // by keeping the ID the same, we have fewer other parts of the state to modify.
          clipCreationIntents.map(updateFn).filter(isValidClipCreationIntent),
          track.clipCreationIntents.map((c) =>
            clipCreationIntentIds.includes(c.id) ? { ...c, id: uuidv4() } : c
          ) // change the ID of the ACTUAL original clip.
        ),
      };
    }),
  });
}
