import { useCallback } from 'react';
import { useJamClient } from '../context/JamClientContext';
import {
  ChannelGroupIds,
  server_to_client_instrument_map,
  client_to_server_instrument_map
} from '../helpers/globals';

const logger = console;

export default function useTrackHelpers() {
  const jamClient = useJamClient();

  const getTrackInfo = useCallback(async (masterTracks) => {
    if (masterTracks === undefined) {
      masterTracks = await jamClient.SessionGetAllControlState(true);
    }

    const userTracks = await getUserTracks(masterTracks);
    const backingTracks = await getBackingTracks(masterTracks);
    const metronomeTracks = await getTracks(ChannelGroupIds.MetronomeGroup, masterTracks);

    return {
      userTracks,
      backingTracks,
      metronomeTracks
    };
  }, [jamClient]);

  const getTracks = useCallback(async (groupId, allTracks) => {
    const tracks = [];

    if (!allTracks) {
      allTracks = await jamClient.SessionGetAllControlState(true);
    }

    for (const track of allTracks) {
      if (track.group_id === groupId) {
        tracks.push(track);
      }
    }

    return tracks;
  }, [jamClient]);

  const getBackingTracks = useCallback(async (allTracks) => {
    const mediaTracks = await getTracks(ChannelGroupIds.MediaTrackGroup, allTracks);

    const backingTracks = [];
    mediaTracks.forEach((mediaTrack) => {
      if (mediaTrack.media_type === "BackingTrack" && !mediaTrack.managed) {
        const track = {};
        track.client_track_id = mediaTrack.persisted_track_id;
        track.client_resource_id = mediaTrack.rid;
        track.filename = mediaTrack.filename;
        backingTracks.push(track);
      }
    });

    return backingTracks;
  }, [getTracks]);

  const getUserTracks = useCallback(async (allTracks) => {
    const localMusicTracks = [];
    const localMidiTracks = [];

    const audioTracks = await getTracks(ChannelGroupIds.AudioInputMusicGroup, allTracks);
    const midiTracks = await getTracks(ChannelGroupIds.MidiInputMusicGroup, allTracks);
    localMusicTracks.push(...audioTracks, ...midiTracks);

    const trackObjects = [];

    for (const track of localMusicTracks) {
      const trackObj = {};
      trackObj.client_track_id = track.id;
      trackObj.client_resource_id = track.rid;

      if (track.instrument_id === 0) {
        trackObj.instrument_id = server_to_client_instrument_map["Other"].server_id;
      } else {
        const instrument = client_to_server_instrument_map[track.instrument_id];
        if (instrument) {
          trackObj.instrument_id = instrument.server_id;
        } else {
          logger.debug("backend reported an invalid instrument ID of " + track.instrument_id);
          trackObj.instrument_id = 'other';
        }
      }

      trackObj.sound = track.stereo ? "stereo" : "mono";
      trackObjects.push(trackObj);
    }

    return trackObjects;
  }, [getTracks]);

  return {
    getTrackInfo,
    getTracks,
    getBackingTracks,
    getUserTracks
  };
}
