import {
  getSelectableTrackIds,
  getTracksAndExpandedTakeLanes,
} from './selectors';
import { AFTER_LAST_TRACK, StudioProjectState } from './types';

export const countTracksBetween = (
  startTrackId: string,
  endTrackId: string,
  state: StudioProjectState
) => {
  let increment = 0;
  let count = 0;
  const trackIds = getSelectableTrackIds(state);

  for (const trackId of trackIds) {
    count += increment;

    if (trackId === startTrackId && increment === 0) {
      increment = 1;
    }

    if (trackId === endTrackId && increment === 0) {
      increment = -1;
    }

    if (trackId === startTrackId && increment === -1) {
      increment = 0;
    }

    if (trackId === endTrackId && increment === 1) {
      increment = 0;
    }
  }

  return count;
};

export default function getTrackIdsBetween(
  startTrackId: string,
  endTrackId: string,
  state: StudioProjectState
) {
  const trackIds: string[] = [];
  let foundTrackId = false;
  const tracks = getTracksAndExpandedTakeLanes(state);

  // Handle AFTER_LAST_TRACK specially
  if (startTrackId === AFTER_LAST_TRACK || endTrackId === AFTER_LAST_TRACK) {
    if (startTrackId === AFTER_LAST_TRACK && endTrackId === AFTER_LAST_TRACK) {
      return [AFTER_LAST_TRACK];
    }

    if (startTrackId === AFTER_LAST_TRACK) {
      // Select from endTrackId to AFTER_LAST_TRACK
      let foundEnd = false;
      for (const track of tracks) {
        if (track.id === endTrackId) {
          foundEnd = true;
          trackIds.push(track.id);
        } else if (foundEnd) {
          trackIds.push(track.id);
        }
      }
      trackIds.push(AFTER_LAST_TRACK);
      return trackIds;
    }

    if (endTrackId === AFTER_LAST_TRACK) {
      // Select from startTrackId to AFTER_LAST_TRACK
      let foundStart = false;
      for (const track of tracks) {
        if (track.id === startTrackId) {
          foundStart = true;
          trackIds.push(track.id);
        } else if (foundStart) {
          trackIds.push(track.id);
        }
      }
      trackIds.push(AFTER_LAST_TRACK);
      return trackIds;
    }
  }

  for (const track of tracks) {
    if (track.id === startTrackId) {
      trackIds.push(track.id);
      foundTrackId = !foundTrackId;
    }

    if (track.id === endTrackId) {
      if (track.id !== startTrackId) trackIds.push(track.id);
      foundTrackId = !foundTrackId;
    }

    if (track.id !== startTrackId && track.id !== endTrackId && foundTrackId) {
      trackIds.push(track.id);
    }
  }
  return trackIds;
}
