import { Controller } from "@hotwired/stimulus"

const INSTRUMENTS = [
  [
   "/audio/vibes/B3.mp3",
   "/audio/vibes/C3.mp3",
   "/audio/vibes/D4.mp3",
   "/audio/vibes/E3.mp3",
   "/audio/vibes/Fsharp4.mp3",
   "/audio/vibes/G3.mp3"
  ],
  [
    "/audio/banjo/B3.mp3",
    "/audio/banjo/C3.mp3",
    "/audio/banjo/D4.mp3",
    "/audio/banjo/E3.mp3",
    "/audio/banjo/Fsharp4.mp3",
    "/audio/banjo/G3.mp3"
  ],
  [
    "/audio/harpsichord/B3.mp3",
    "/audio/harpsichord/C3.mp3",
    "/audio/harpsichord/D4.mp3",
    "/audio/harpsichord/E3.mp3",
    "/audio/harpsichord/Fsharp4.mp3",
    "/audio/harpsichord/G3.mp3"
  ],
  [
    "/audio/mandolin/B3.mp3",
    "/audio/mandolin/C3.mp3",
    "/audio/mandolin/D4.mp3",
    "/audio/mandolin/E3.mp3",
    "/audio/mandolin/Fsharp4.mp3",
    "/audio/mandolin/G3.mp3"
  ],
  [
   "/audio/piano/B3.mp3",
   "/audio/piano/C3.mp3",
   "/audio/piano/D4.mp3",
   "/audio/piano/E3.mp3",
   "/audio/piano/Fsharp4.mp3",
   "/audio/piano/G3.mp3"
  ],
]

export default class extends Controller {
  static targets = [ "container" ]

  connect() {
    this.instrumentIndex = 0
    this.preloadedAudioFiles = []
    document.addEventListener("keydown", this.handleKeyDown.bind(this));
  }

  disconnect() {
    document.removeEventListener("keydown", this.handleKeyDown.bind(this));
  }

  handleKeyDown(event) {
    if (event.shiftKey) {
      this.instrumentIndex = this.#getInstrumentIndex(event)

      if (this.instrumentIndex < INSTRUMENTS.length) {
        this.#preloadAudioFiles(this.instrumentIndex)
      }
    }
  }

  dragEnter(event) {
    event.preventDefault()
    const container = this.#containerContaining(event.target)

    if (!container) { return }

    if (container !== this.sourceContainer && event.shiftKey) {
      this.#playSound()
    }
  }

  #getInstrumentIndex(event) {
    const number = Number(event.code.replace("Digit", ""))
    return isNaN(number) ? 0 : number
  }

  #preloadAudioFiles(instrumentIndex) {
    this.preloadedAudioFiles = []
    const audioFiles = INSTRUMENTS[instrumentIndex];

    if (audioFiles) {
      this.preloadedAudioFiles = audioFiles.map(file => {
        const audio = new Audio(file)
        audio.load()
        return audio
      })
    }
  }

  #containerContaining(element) {
    return this.containerTargets.find(container => container.contains(element) || container === element)
  }

  #playSound() {
    const randomIndex = Math.floor(Math.random() * this.preloadedAudioFiles.length)
    const audio = this.preloadedAudioFiles[randomIndex]
    const audioInstance = new Audio(audio.src)

    audioInstance.play()
  }
}
