import {
  getSelectionEndBeats,
  getSelectionStartBeats,
  getTracksAndTakeLanes,
} from '../selectors';
import { StudioProjectState } from '../types';

export default function selectAll(
  state: StudioProjectState,
  andSelectAllTracks: boolean = false
) {
  const tracks = getTracksAndTakeLanes(state);
  const minBeatOnSelectedTracks = tracks
    .filter(
      (t) =>
        t.clips.length &&
        (andSelectAllTracks || state.selection.trackIds.includes(t.id))
    )
    .reduce((min, track) => {
      return Math.min(
        min,
        track.clips.reduce(
          (min, clip) => Math.min(min, clip.startBeats),
          Infinity
        )
      );
    }, Infinity);

  const maxBeatOnSelectedTracks = tracks
    .filter(
      (t) =>
        t.clips.length &&
        (andSelectAllTracks || state.selection.trackIds.includes(t.id))
    )
    .reduce((max, track) => {
      return Math.max(
        max,
        track.clips.reduce(
          (max, clip) => Math.max(max, clip.endBeats),
          -Infinity
        )
      );
    }, -Infinity);

  if (
    !Number.isFinite(maxBeatOnSelectedTracks) ||
    !Number.isFinite(minBeatOnSelectedTracks)
  ) {
    return state;
  }

  if (
    !andSelectAllTracks &&
    getSelectionStartBeats(state) === minBeatOnSelectedTracks &&
    getSelectionEndBeats(state) === maxBeatOnSelectedTracks
  ) {
    return selectAll(state, true);
  }

  return {
    ...state,
    selection: {
      ...state.selection,
      trackIds: andSelectAllTracks
        ? tracks.map((t) => t.id)
        : state.selection.trackIds,
      anchorBeats: minBeatOnSelectedTracks,
      focusBeats: maxBeatOnSelectedTracks,
    },
  };

  return state;
}
