async function loadInstrumentsConfig() {
  const response = await fetch("/assets/instruments/instruments.json");
  return await response.json();
}

async function fetchAudioData(url) {
  const response = await fetch(url);
  const arrayBuffer = await response.arrayBuffer();
  return arrayBuffer;
}

async function decodeAudioData(context, arrayBuffer) {
  return new Promise((resolve, reject) => {
    context.decodeAudioData(arrayBuffer, resolve, reject);
  });
}

async function loadAudioSamples(context, directory, filenames) {
  const audioFiles = filenames;

  const audioBuffers = {};
  for (const file of audioFiles) {
    const arrayBuffer = await fetchAudioData(`${directory}/${file}`);
    const audioBuffer = await decodeAudioData(context, arrayBuffer);
    const fileName = file.split("/").pop(); // Extract filename without path for reference
    audioBuffers[fileName] = audioBuffer;
  }

  return audioBuffers;
}

async function fetchImageData(url) {
  const response = await fetch(url);
  const blob = await response.blob();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.onerror = reject;
    reader.readAsDataURL(blob); // Convert to base64
  });
}

export async function loadInstruments() {
  const instrumentsConfig = await loadInstrumentsConfig();
  const context = new (window.AudioContext || window.webkitAudioContext)();
  const instruments = {};

  for (const [instrument, config] of Object.entries(instrumentsConfig)) {
    const samples = await loadAudioSamples(
      context,
      config.directory,
      config.filenames
    );
    const imageData = await fetchImageData(
      `${config.directory}/${config.image.filename}`
    );
    instruments[instrument] = {
      samples: samples,
      image: imageData,
      yPos: config.image.yPos, // Store base64-encoded image data
      midiChannelName: config["midi-channel-name"],
    };
  }

  return instruments;
}
