<template>
  <div class="music-player">
    <!-- Aurora background -->
    <div class="aurora-bg">
      <div class="aurora-orb"></div>
      <div class="aurora-orb"></div>
      <div class="aurora-orb"></div>
      <div class="aurora-orb"></div>
    </div>

    <!-- Header -->
    <header class="glass-strong" style="padding: 20px; margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
      <h1 style="font-size: 2rem; font-weight: 700; background: linear-gradient(45deg, var(--accent-primary), var(--accent-secondary)); -webkit-background-clip: text; -webkit-text-fill-color: transparent;">
        🎵 RepoDructor
      </h1>
      
      <div style="display: flex; gap: 10px; align-items: center;">
        <!-- Theme toggle -->
        <button @click="toggleTheme" class="btn-icon" title="Toggle theme">
          <span v-if="isDark">☀️</span>
          <span v-else>🌙</span>
        </button>
        
        <!-- Shuffle -->
        <button @click="toggleShuffle" class="btn-icon" :class="{ 'active': isShuffled }" title="Shuffle">
          🔀
        </button>
        
        <!-- Repeat modes -->
        <button @click="cycleRepeat" class="btn-icon" title="Repeat mode">
          <span v-if="repeatMode === 'none'">🔁</span>
          <span v-else-if="repeatMode === 'all'">🔂</span>
          <span v-else>🔂</span>
        </button>
      </div>
    </header>

    <!-- Now Playing -->
    <div v-if="currentTrack" class="glass" style="padding: 20px; margin-bottom: 20px; text-align: center;">
      <h2 style="font-size: 1.5rem; margin-bottom: 10px;">Now Playing</h2>
      <p style="font-size: 1.2rem; font-weight: 600; color: var(--accent-primary);">
        {{ currentTrack.name }}
      </p>
      <p style="color: var(--text-secondary); margin-top: 5px;">
        Duration: {{ formatTime(currentTrack.duration || 0) }}
      </p>
    </div>

    <!-- Track List -->
    <div class="track-list">
      <h3 style="margin-bottom: 15px; font-size: 1.3rem;">Your Music Library</h3>
      
      <div v-if="loading" style="text-align: center; padding: 40px;">
        <p>Loading your music...</p>
      </div>
      
      <div v-else-if="tracks.length === 0" style="text-align: center; padding: 40px;">
        <p>No music files found. Add some music files to the /music folder!</p>
      </div>
      
      <div v-else>
        <div 
          v-for="(track, index) in displayTracks" 
          :key="track.name"
          @click="playTrack(track, index)"
          class="track-item"
          :class="{ active: currentTrack?.name === track.name }"
          style="display: flex; justify-content: space-between; align-items: center;"
        >
          <div>
            <p style="font-weight: 500;">{{ track.name }}</p>
            <p style="font-size: 0.9rem; color: var(--text-secondary);">
              {{ formatTime(track.duration || 0) }}
            </p>
          </div>
          
          <div style="display: flex; gap: 10px; align-items: center;">
            <span v-if="currentTrack?.name === track.name && !isPlaying">⏸️</span>
            <span v-else-if="currentTrack?.name === track.name && isPlaying">▶️</span>
            <span v-else>🎵</span>
          </div>
        </div>
      </div>
    </div>

    <!-- Player Controls -->
    <div class="player-controls" v-if="currentTrack">
      <!-- Previous -->
      <button @click="previousTrack" class="btn-icon" title="Previous">
        ⏮️
      </button>
      
      <!-- Play/Pause -->
      <button @click="togglePlay" class="btn-icon" style="width: 60px; height: 60px; font-size: 1.5rem;" title="Play/Pause">
        <span v-if="isPlaying">⏸️</span>
        <span v-else>▶️</span>
      </button>
      
      <!-- Next -->
      <button @click="nextTrack" class="btn-icon" title="Next">
        ⏭️
      </button>
      
      <!-- Progress Bar -->
      <div class="progress-bar" @click="seekTo" ref="progressBar">
        <div class="progress-fill" :style="{ width: progressPercent + '%' }"></div>
      </div>
      
      <!-- Time -->
      <div style="min-width: 100px; text-align: center; font-size: 0.9rem;">
        {{ formatTime(currentTime) }} / {{ formatTime(duration) }}
      </div>
      
      <!-- Volume -->
      <div class="volume-control">
        <span>🔊</span>
        <div class="volume-slider" @click="setVolume" ref="volumeSlider">
          <div class="progress-fill" :style="{ width: volume * 100 + '%' }"></div>
        </div>
      </div>
    </div>

    <!-- Audio Element -->
    <audio 
      ref="audioPlayer"
      @loadedmetadata="onLoadedMetadata"
      @timeupdate="onTimeUpdate"
      @ended="onTrackEnded"
      @canplay="onCanPlay"
      @error="onAudioError"
    ></audio>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { useLocalStorage } from '@vueuse/core'

// Reactive state
const tracks = ref([])
const currentTrack = ref(null)
const currentTrackIndex = ref(0)
const isPlaying = ref(false)
const currentTime = ref(0)
const duration = ref(0)
const volume = ref(0.7)
const loading = ref(true)

// Theme
const isDark = useLocalStorage('theme-dark', false)

// Playback modes
const isShuffled = useLocalStorage('shuffle', false)
const repeatMode = useLocalStorage('repeat', 'none') // 'none', 'all', 'one'
const shuffledIndices = ref([])

// Refs
const audioPlayer = ref(null)
const progressBar = ref(null)
const volumeSlider = ref(null)

// Computed
const progressPercent = computed(() => {
  if (duration.value === 0) return 0
  return (currentTime.value / duration.value) * 100
})

const displayTracks = computed(() => {
  if (isShuffled.value && shuffledIndices.value.length > 0) {
    return shuffledIndices.value.map(index => tracks.value[index])
  }
  return tracks.value
})

// Methods
const loadTracks = async () => {
  try {
    const response = await $fetch('/api/music')
    tracks.value = response.tracks
    if (tracks.value.length > 0) {
      generateShuffledIndices()
    }
  } catch (error) {
    console.error('Failed to load tracks:', error)
  } finally {
    loading.value = false
  }
}

const generateShuffledIndices = () => {
  shuffledIndices.value = Array.from({ length: tracks.value.length }, (_, i) => i)
  // Fisher-Yates shuffle algorithm for truly random results
  for (let i = shuffledIndices.value.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
    ;[shuffledIndices.value[i], shuffledIndices.value[j]] = [shuffledIndices.value[j], shuffledIndices.value[i]]
  }
}

const playTrack = async (track, index) => {
  currentTrack.value = track
  currentTrackIndex.value = isShuffled.value 
    ? shuffledIndices.value.indexOf(tracks.value.indexOf(track))
    : index
  
  if (audioPlayer.value) {
    // Clear previous audio data
    if (audioPlayer.value.currentBlobUrl) {
      URL.revokeObjectURL(audioPlayer.value.currentBlobUrl)
      audioPlayer.value.currentBlobUrl = null
    }
    
    try {
      // Fetch and preload entire song into memory
      const encodedName = encodeURIComponent(track.name)
      const response = await fetch(`/api/music/${encodedName}`)
      const blob = await response.blob()
      const audioUrl = URL.createObjectURL(blob)
      
      // Store reference to revoke later
      audioPlayer.value.currentBlobUrl = audioUrl
      audioPlayer.value.src = audioUrl
      console.log('Preloaded track into memory:', track.name)
      audioPlayer.value.load()
      
      // Auto-play when ready
      audioPlayer.value.addEventListener('canplay', () => {
        audioPlayer.value.play()
      }, { once: true })
    } catch (error) {
      console.error('Failed to preload track:', error)
      // Fallback to streaming
      const encodedName = encodeURIComponent(track.name)
      audioPlayer.value.src = `/api/music/${encodedName}`
      audioPlayer.value.load()
      
      // Auto-play when ready (fallback)
      audioPlayer.value.addEventListener('canplay', () => {
        audioPlayer.value.play()
      }, { once: true })
    }
  }
}

const togglePlay = () => {
  if (!audioPlayer.value || !currentTrack.value) return
  
  if (isPlaying.value) {
    audioPlayer.value.pause()
  } else {
    audioPlayer.value.play()
  }
}

const nextTrack = () => {
  if (tracks.value.length === 0) return
  
  let nextIndex
  const trackList = isShuffled.value ? shuffledIndices.value : Array.from({ length: tracks.value.length }, (_, i) => i)
  
  if (repeatMode.value === 'one') {
    // Repeat current track
    nextIndex = currentTrackIndex.value
  } else {
    // Move to next track
    nextIndex = (currentTrackIndex.value + 1) % trackList.length
    
    if (nextIndex === 0 && repeatMode.value === 'none') {
      // End of playlist and no repeat
      isPlaying.value = false
      return
    }
  }
  
  const actualIndex = isShuffled.value ? trackList[nextIndex] : nextIndex
  const track = tracks.value[actualIndex]
  
  playTrack(track, actualIndex)
  
  setTimeout(() => {
    if (audioPlayer.value) {
      audioPlayer.value.play()
    }
  }, 100)
}

const previousTrack = () => {
  if (tracks.value.length === 0) return
  
  const trackList = isShuffled.value ? shuffledIndices.value : Array.from({ length: tracks.value.length }, (_, i) => i)
  const prevIndex = currentTrackIndex.value === 0 ? trackList.length - 1 : currentTrackIndex.value - 1
  
  const actualIndex = isShuffled.value ? trackList[prevIndex] : prevIndex
  const track = tracks.value[actualIndex]
  
  playTrack(track, actualIndex)
  
  setTimeout(() => {
    if (audioPlayer.value) {
      audioPlayer.value.play()
    }
  }, 100)
}

const toggleShuffle = () => {
  isShuffled.value = !isShuffled.value
  if (isShuffled.value) {
    generateShuffledIndices()
  }
}

const cycleRepeat = () => {
  const modes = ['none', 'all', 'one']
  const currentIndex = modes.indexOf(repeatMode.value)
  repeatMode.value = modes[(currentIndex + 1) % modes.length]
}

const toggleTheme = () => {
  isDark.value = !isDark.value
}

const formatTime = (seconds) => {
  if (!seconds || isNaN(seconds)) return '0:00'
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

const seekTo = (event) => {
  if (!audioPlayer.value || !progressBar.value) return
  
  const rect = progressBar.value.getBoundingClientRect()
  const percent = (event.clientX - rect.left) / rect.width
  const newTime = percent * duration.value
  
  audioPlayer.value.currentTime = newTime
}

const setVolume = (event) => {
  if (!volumeSlider.value) return
  
  const rect = volumeSlider.value.getBoundingClientRect()
  const percent = (event.clientX - rect.left) / rect.width
  volume.value = Math.max(0, Math.min(1, percent))
  
  if (audioPlayer.value) {
    audioPlayer.value.volume = volume.value
  }
}

// Audio event handlers
const onLoadedMetadata = () => {
  if (audioPlayer.value) {
    duration.value = audioPlayer.value.duration
    audioPlayer.value.volume = volume.value
  }
}

const onAudioError = (error) => {
  console.error('Audio error:', error)
  console.error('Failed to load:', currentTrack.value?.name)
  // Try next track if current fails
  nextTrack()
}

const onTimeUpdate = () => {
  if (audioPlayer.value) {
    currentTime.value = audioPlayer.value.currentTime
  }
}

const onTrackEnded = () => {
  isPlaying.value = false
  nextTrack()
}

const onCanPlay = () => {
  // Track is ready to play
}

// Watchers
watch(isDark, (newValue) => {
  if (process.client) {
    document.documentElement.setAttribute('data-theme', newValue ? 'dark' : 'light')
  }
}, { immediate: true })

watch(() => audioPlayer.value, (newAudio) => {
  if (newAudio) {
    newAudio.addEventListener('play', () => { isPlaying.value = true })
    newAudio.addEventListener('pause', () => { isPlaying.value = false })
  }
})

// Cleanup function
const cleanupAudio = () => {
  if (audioPlayer.value?.currentBlobUrl) {
    URL.revokeObjectURL(audioPlayer.value.currentBlobUrl)
    audioPlayer.value.currentBlobUrl = null
  }
}

// Handle mobile browser UI bars
const handleViewportChange = () => {
  if (!process.client) return
  
  const vh = window.innerHeight
  const dvh = window.visualViewport ? window.visualViewport.height : vh
  const diff = vh - dvh
  
  const playerControls = document.querySelector('.player-controls')
  if (playerControls) {
    if (diff > 50) {
      // Browser bars are visible, move controls up
      playerControls.style.setProperty('--browser-bar-height', `${diff}px`)
      playerControls.classList.add('browser-bars-visible')
    } else {
      // Browser bars hidden, controls to bottom
      playerControls.style.setProperty('--browser-bar-height', '0px')
      playerControls.classList.remove('browser-bars-visible')
    }
  }
}

// Lifecycle
onMounted(() => {
  loadTracks()
  if (process.client) {
    document.documentElement.setAttribute('data-theme', isDark.value ? 'dark' : 'light')
    
    // Handle mobile browser UI changes
    handleViewportChange()
    window.addEventListener('resize', handleViewportChange)
    if (window.visualViewport) {
      window.visualViewport.addEventListener('resize', handleViewportChange)
    }
    
    // Cleanup when page unloads
    window.addEventListener('beforeunload', cleanupAudio)
    window.addEventListener('pagehide', cleanupAudio)
  }
})

onUnmounted(() => {
  cleanupAudio()
  if (process.client) {
    window.removeEventListener('beforeunload', cleanupAudio)
    window.removeEventListener('pagehide', cleanupAudio)
    window.removeEventListener('resize', handleViewportChange)
    if (window.visualViewport) {
      window.visualViewport.removeEventListener('resize', handleViewportChange)
    }
  }
})
</script>

<style scoped>
.active {
  background: linear-gradient(45deg, var(--accent-primary), var(--accent-secondary)) !important;
  color: white !important;
}

.btn-icon.active {
  background: var(--accent-primary) !important;
  color: white !important;
}
</style>