<template>
  <div class="video-player" @mousemove="showControls" @mouseleave="hideControls">
    <video
      ref="videoElement"
      class="video-element"
      preload="auto"
      @loadedmetadata="onLoadedMetadata"
      @timeupdate="onTimeUpdate"
      @progress="onProgress"
      @ended="onEnded"
      @click="togglePlay"
    >
      Tu navegador no soporta el elemento de video.
    </video>

    <div class="controls-overlay" :class="{ visible: controlsVisible || !isPlaying }">
      <div class="progress-container" @click="seek">
        <div class="progress-bar">
          <!-- Barra de buffer (lo que está cargado) -->
          <div class="progress-buffered" :style="{ width: bufferedPercent + '%' }"></div>
          <!-- Barra de progreso (lo que está reproduciéndose) -->
          <div class="progress-filled" :style="{ width: progressPercent + '%' }">
            <div class="progress-thumb"></div>
          </div>
        </div>
        <div class="time-display">
          <span>{{ formatTime(currentTime) }}</span>
          <span class="buffered-info" v-if="bufferedPercent > progressPercent">
            💾 {{ Math.round(bufferedPercent) }}% cacheado
          </span>
          <span>{{ formatTime(duration) }}</span>
        </div>
      </div>

      <div class="controls-bottom">
        <button @click="togglePlay" class="control-btn play-btn">
          <span v-if="!isPlaying">▶</span>
          <span v-else>⏸</span>
        </button>

        <div class="volume-control">
          <button @click="toggleMute" class="control-btn">
            <span v-if="!isMuted && volume > 0.5">🔊</span>
            <span v-else-if="!isMuted && volume > 0">🔉</span>
            <span v-else>🔇</span>
          </button>
          <input
            type="range"
            min="0"
            max="100"
            v-model="volumePercent"
            @input="changeVolume"
            class="volume-slider"
          />
        </div>

        <div class="spacer"></div>

        <button @click="changeSpeed" class="control-btn speed-btn">
          {{ playbackSpeed }}x
        </button>

        <!-- Botón de calidad -->
        <div class="quality-selector" v-if="qualities && qualities.length > 1">
          <button @click="toggleQualityMenu" class="control-btn quality-btn">
            {{ currentQualityLabel }}
          </button>
          <div v-if="qualityMenuOpen" class="quality-menu">
            <div
              v-for="quality in qualities"
              :key="quality.quality"
              @click="changeQuality(quality)"
              class="quality-option"
              :class="{ active: currentQuality === quality.quality }"
            >
              <span class="quality-label">{{ quality.label }}</span>
              <span v-if="currentQuality === quality.quality" class="quality-check">✓</span>
            </div>
          </div>
        </div>

        <button @click="toggleFullscreen" class="control-btn">
          <span v-if="!isFullscreen">⛶</span>
          <span v-else>⛶</span>
        </button>
      </div>
    </div>

    <div v-if="!isPlaying && currentTime === 0" class="play-overlay" @click="togglePlay">
      <div class="play-icon">▶</div>
    </div>

    <!-- Banner de calidad inicial -->
    <div v-if="showQualityBanner && qualities && qualities.length > 1" class="quality-banner">
      <div class="quality-banner-content">
        <span class="quality-banner-icon">ℹ️</span>
        <span class="quality-banner-text">
          Reproduciendo en <strong>{{ currentQualityLabel }}</strong>.
          Puedes cambiar a mayor calidad usando el selector ⚙️
        </span>
        <button @click="dismissQualityBanner" class="quality-banner-close">✕</button>
      </div>
    </div>

    <!-- Indicador de cambio de calidad -->
    <div v-if="qualityChanging" class="quality-indicator">
      <div class="quality-indicator-content">
        <div class="spinner"></div>
        <span>Cambiando a {{ newQualityLabel }}...</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import Hls from 'hls.js'

interface Quality {
  quality: string
  label: string
  url: string
  file: string
  isHLS?: boolean
}

const props = defineProps<{
  videoUrl: string
  qualities?: Quality[]
}>()

const videoElement = ref<HTMLVideoElement | null>(null)
const isPlaying = ref(false)
const currentTime = ref(0)
const duration = ref(0)
const volume = ref(1)
const isMuted = ref(false)
const volumePercent = ref(100)
const playbackSpeed = ref(1)
const isFullscreen = ref(false)
const controlsVisible = ref(false)
const qualityMenuOpen = ref(false)
const qualityChanging = ref(false)
const currentQuality = ref('480p')  // Cambio: Por defecto 480p
const newQualityLabel = ref('')
const bufferedPercent = ref(0)
const showQualityBanner = ref(true)  // Banner de calidad
let controlsTimeout: NodeJS.Timeout | null = null
let hls: Hls | null = null

const currentVideoUrl = ref(props.videoUrl)

const currentQualityLabel = computed(() => {
  if (!props.qualities || props.qualities.length === 0) return '480P'
  const quality = props.qualities.find(q => q.quality === currentQuality.value)
  return quality?.label || '480P'
})

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

// Función para inicializar HLS
const initHLS = (url: string) => {
  if (!videoElement.value) return

  console.log('Inicializando HLS con URL:', url)

  // Limpiar instancia anterior de HLS
  if (hls) {
    hls.destroy()
    hls = null
  }

  // Si el navegador soporta HLS nativamente (Safari)
  if (videoElement.value.canPlayType('application/vnd.apple.mpegurl')) {
    console.log('Usando soporte nativo de HLS')
    videoElement.value.src = url
    videoElement.value.load()
    return
  }

  // Si hls.js está soportado
  if (Hls.isSupported()) {
    console.log('Usando hls.js')
    hls = new Hls({
      enableWorker: true,
      lowLatencyMode: false,
      backBufferLength: 90,
      maxBufferLength: 30,
      maxMaxBufferLength: 60
    })

    hls.loadSource(url)
    hls.attachMedia(videoElement.value)

    hls.on(Hls.Events.MANIFEST_PARSED, () => {
      console.log('HLS manifest cargado correctamente')
    })

    hls.on(Hls.Events.ERROR, (event, data) => {
      console.error('Error en HLS:', data)
      if (data.fatal) {
        console.error('Error fatal en HLS:', data)
        switch (data.type) {
          case Hls.ErrorTypes.NETWORK_ERROR:
            console.log('Error de red, intentando recuperar...')
            hls?.startLoad()
            break
          case Hls.ErrorTypes.MEDIA_ERROR:
            console.log('Error de media, intentando recuperar...')
            hls?.recoverMediaError()
            break
          default:
            console.log('Error irrecuperable')
            hls?.destroy()
            break
        }
      }
    })
  } else {
    console.error('HLS no soportado en este navegador')
  }
}

// Inicializar con calidad 480p por defecto
watch(() => props.videoUrl, (newUrl) => {
  if (!newUrl) return

  // Buscar 480p si está disponible, sino usar la URL original
  let urlToUse = newUrl

  if (props.qualities && props.qualities.length > 0) {
    // Buscar calidad 480p
    const quality480p = props.qualities.find(q => q.quality === '480p')
    if (quality480p) {
      urlToUse = quality480p.url
      currentQuality.value = '480p'
    } else {
      // Si no hay 480p, usar la primera calidad disponible
      const firstQuality = props.qualities[0]
      urlToUse = firstQuality.url
      currentQuality.value = firstQuality.quality
    }
  }

  currentVideoUrl.value = urlToUse

  // Esperar a que el elemento de video esté disponible
  nextTick(() => {
    if (!videoElement.value) return

    // Si es HLS (termina en .m3u8), usar HLS.js
    if (urlToUse.endsWith('.m3u8')) {
      initHLS(urlToUse)
    } else {
      // Video normal
      if (hls) {
        hls.destroy()
        hls = null
      }
      videoElement.value.src = urlToUse
      videoElement.value.load()
    }
  })
}, { immediate: true })

const togglePlay = () => {
  if (!videoElement.value) return

  if (isPlaying.value) {
    videoElement.value.pause()
    isPlaying.value = false
  } else {
    videoElement.value.play()
    isPlaying.value = true
  }
}

const onLoadedMetadata = () => {
  if (!videoElement.value) return
  duration.value = videoElement.value.duration
}

const onTimeUpdate = () => {
  if (!videoElement.value) return
  currentTime.value = videoElement.value.currentTime
}

const onProgress = () => {
  if (!videoElement.value || !duration.value) return

  // Calcular cuánto del video está cargado en buffer
  const buffered = videoElement.value.buffered
  if (buffered.length > 0) {
    // Obtener el rango de buffer más grande que contiene la posición actual
    let bufferedEnd = 0
    for (let i = 0; i < buffered.length; i++) {
      const start = buffered.start(i)
      const end = buffered.end(i)
      if (start <= currentTime.value && end > bufferedEnd) {
        bufferedEnd = end
      }
    }
    bufferedPercent.value = (bufferedEnd / duration.value) * 100
  }
}

const onEnded = () => {
  isPlaying.value = false
  currentTime.value = 0
}

const seek = (e: MouseEvent) => {
  if (!videoElement.value) return
  const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()
  const percent = (e.clientX - rect.left) / rect.width
  videoElement.value.currentTime = percent * duration.value
}

const toggleMute = () => {
  if (!videoElement.value) return
  isMuted.value = !isMuted.value
  videoElement.value.muted = isMuted.value
}

const changeVolume = () => {
  if (!videoElement.value) return
  volume.value = volumePercent.value / 100
  videoElement.value.volume = volume.value
  if (volume.value > 0) {
    isMuted.value = false
    videoElement.value.muted = false
  }
}

const changeSpeed = () => {
  if (!videoElement.value) return
  const speeds = [0.5, 0.75, 1, 1.25, 1.5, 2]
  const currentIndex = speeds.indexOf(playbackSpeed.value)
  const nextIndex = (currentIndex + 1) % speeds.length
  playbackSpeed.value = speeds[nextIndex]
  videoElement.value.playbackRate = playbackSpeed.value
}

const toggleQualityMenu = () => {
  qualityMenuOpen.value = !qualityMenuOpen.value
}

const changeQuality = async (quality: Quality) => {
  if (!videoElement.value || currentQuality.value === quality.quality) {
    qualityMenuOpen.value = false
    return
  }

  // Guardar el estado actual
  const wasPlaying = isPlaying.value
  const savedTime = currentTime.value

  // Mostrar indicador
  qualityChanging.value = true
  newQualityLabel.value = quality.label
  qualityMenuOpen.value = false

  // Cambiar la calidad
  currentQuality.value = quality.quality
  currentVideoUrl.value = quality.url

  // Si es HLS, usar initHLS
  if (quality.url.endsWith('.m3u8')) {
    initHLS(quality.url)
  } else {
    // Video normal
    if (hls) {
      hls.destroy()
      hls = null
    }
    videoElement.value.src = quality.url
  }

  // Esperar a que el video cargue
  await nextTick()

  if (videoElement.value) {
    // Restaurar el tiempo
    videoElement.value.currentTime = savedTime

    // Restaurar la reproducción si estaba reproduciéndose
    if (wasPlaying) {
      try {
        await videoElement.value.play()
        isPlaying.value = true
      } catch (error) {
        console.error('Error al reanudar reproducción:', error)
      }
    }
  }

  // Ocultar indicador después de un momento
  setTimeout(() => {
    qualityChanging.value = false
  }, 1000)
}

const toggleFullscreen = () => {
  if (!document.fullscreenElement) {
    videoElement.value?.parentElement?.requestFullscreen()
    isFullscreen.value = true
  } else {
    document.exitFullscreen()
    isFullscreen.value = false
  }
}

const dismissQualityBanner = () => {
  showQualityBanner.value = false
}

// Auto-ocultar banner después de 10 segundos
onMounted(() => {
  setTimeout(() => {
    showQualityBanner.value = false
  }, 10000)
})

// Ocultar banner al cambiar calidad
watch(currentQuality, () => {
  showQualityBanner.value = false
})

const formatTime = (seconds: number) => {
  if (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 showControls = () => {
  controlsVisible.value = true
  if (controlsTimeout) clearTimeout(controlsTimeout)
  controlsTimeout = setTimeout(() => {
    if (isPlaying.value) {
      controlsVisible.value = false
    }
  }, 3000)
}

const hideControls = () => {
  if (controlsTimeout) clearTimeout(controlsTimeout)
  if (isPlaying.value) {
    controlsVisible.value = false
  }
}

onUnmounted(() => {
  if (controlsTimeout) clearTimeout(controlsTimeout)
  if (hls) {
    hls.destroy()
    hls = null
  }
})
</script>

<style scoped>
.video-player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 20px;
  overflow: hidden;
  box-shadow:
    0 0 40px rgba(0, 255, 255, 0.3),
    0 0 80px rgba(255, 0, 255, 0.2),
    inset 0 0 60px rgba(0, 0, 0, 0.5);
}

.video-element {
  width: 100%;
  height: 100%;
  object-fit: contain;
  cursor: pointer;
}

.controls-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 20px;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(0, 0, 0, 0.7) 50%,
    transparent 100%
  );
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}

.controls-overlay.visible {
  opacity: 1;
  pointer-events: all;
}

.progress-container {
  margin-bottom: 15px;
  cursor: pointer;
}

.progress-bar {
  height: 6px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  backdrop-filter: blur(10px);
}

.progress-buffered {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: rgba(0, 255, 255, 0.3);
  border-radius: 10px;
  transition: width 0.3s ease;
  z-index: 1;
}

.progress-filled {
  position: relative;
  height: 100%;
  background: linear-gradient(90deg, #00ffff, #ff00ff, #00ffff);
  background-size: 200% 100%;
  animation: shimmer 3s linear infinite;
  border-radius: 10px;
  transition: width 0.1s linear;
  z-index: 2;
}

@keyframes shimmer {
  0% { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

.progress-thumb {
  position: absolute;
  right: -6px;
  top: 50%;
  transform: translateY(-50%);
  width: 12px;
  height: 12px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
}

.time-display {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 8px;
  font-size: 12px;
  color: #fff;
  font-family: monospace;
  text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
  gap: 10px;
}

.buffered-info {
  font-size: 11px;
  color: rgba(0, 255, 255, 0.8);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  animation: pulse-text 2s ease-in-out infinite;
}

@keyframes pulse-text {
  0%, 100% {
    opacity: 0.8;
  }
  50% {
    opacity: 1;
  }
}

.controls-bottom {
  display: flex;
  align-items: center;
  gap: 15px;
}

.control-btn {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
  padding: 10px 15px;
  border-radius: 10px;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.control-btn:hover {
  background: rgba(0, 255, 255, 0.3);
  border-color: rgba(0, 255, 255, 0.5);
  box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
  transform: translateY(-2px);
}

.play-btn {
  font-size: 20px;
}

.volume-control {
  display: flex;
  align-items: center;
  gap: 10px;
}

.volume-slider {
  width: 80px;
  height: 6px;
  -webkit-appearance: none;
  appearance: none;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  outline: none;
  cursor: pointer;
}

.volume-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  background: #fff;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 10px rgba(255, 0, 255, 0.8);
}

.volume-slider::-moz-range-thumb {
  width: 14px;
  height: 14px;
  background: #fff;
  border-radius: 50%;
  cursor: pointer;
  border: none;
  box-shadow: 0 0 10px rgba(255, 0, 255, 0.8);
}

.spacer {
  flex: 1;
}

.speed-btn {
  min-width: 60px;
  font-family: monospace;
}

/* Quality Selector */
.quality-selector {
  position: relative;
}

.quality-btn {
  min-width: 70px;
  font-family: monospace;
  font-weight: 600;
}

.quality-menu {
  position: absolute;
  bottom: 100%;
  right: 0;
  margin-bottom: 10px;
  background: rgba(0, 0, 0, 0.95);
  backdrop-filter: blur(20px);
  border: 1px solid rgba(0, 255, 255, 0.3);
  border-radius: 12px;
  padding: 8px;
  min-width: 140px;
  box-shadow: 0 0 30px rgba(0, 255, 255, 0.4);
  animation: slideUp 0.2s ease;
}

@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.quality-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  cursor: pointer;
  border-radius: 8px;
  transition: all 0.2s ease;
  color: #fff;
  font-size: 14px;
}

.quality-option:hover {
  background: rgba(0, 255, 255, 0.2);
}

.quality-option.active {
  background: rgba(0, 255, 255, 0.3);
  border: 1px solid rgba(0, 255, 255, 0.5);
}

.quality-label {
  font-weight: 600;
  text-transform: uppercase;
}

.quality-check {
  color: #00ffff;
  font-size: 16px;
  margin-left: 10px;
}

/* Quality Indicator */
.quality-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.9);
  backdrop-filter: blur(20px);
  padding: 20px 30px;
  border-radius: 16px;
  border: 1px solid rgba(0, 255, 255, 0.5);
  box-shadow: 0 0 40px rgba(0, 255, 255, 0.6);
  z-index: 100;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.quality-indicator-content {
  display: flex;
  align-items: center;
  gap: 15px;
  color: #fff;
  font-size: 16px;
  font-weight: 600;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top-color: #00ffff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Banner de calidad inicial */
.quality-banner {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  animation: slideDown 0.5s ease;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translate(-50%, -20px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

.quality-banner-content {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(0, 150, 255, 0.95);
  backdrop-filter: blur(20px);
  padding: 15px 25px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 4px 20px rgba(0, 150, 255, 0.4);
  max-width: 90vw;
}

.quality-banner-icon {
  font-size: 20px;
  flex-shrink: 0;
}

.quality-banner-text {
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
}

.quality-banner-text strong {
  font-weight: 700;
  color: #ffff00;
}

.quality-banner-close {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  color: #fff;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
  flex-shrink: 0;
}

.quality-banner-close:hover {
  background: rgba(255, 255, 255, 0.4);
  transform: scale(1.1);
}

.play-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(5px);
}

.play-icon {
  font-size: 80px;
  color: #fff;
  background: rgba(0, 255, 255, 0.2);
  width: 120px;
  height: 120px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid rgba(0, 255, 255, 0.5);
  box-shadow:
    0 0 40px rgba(0, 255, 255, 0.6),
    inset 0 0 40px rgba(0, 255, 255, 0.2);
  transition: all 0.3s ease;
  animation: pulse 2s ease-in-out infinite;
}

.play-overlay:hover .play-icon {
  transform: scale(1.1);
  box-shadow:
    0 0 60px rgba(0, 255, 255, 0.8),
    inset 0 0 40px rgba(0, 255, 255, 0.3);
}

@keyframes pulse {
  0%, 100% {
    box-shadow:
      0 0 40px rgba(0, 255, 255, 0.6),
      inset 0 0 40px rgba(0, 255, 255, 0.2);
  }
  50% {
    box-shadow:
      0 0 60px rgba(0, 255, 255, 0.8),
      inset 0 0 60px rgba(0, 255, 255, 0.3);
  }
}

@media (max-width: 768px) {
  /* Hacer los controles siempre visibles en móvil */
  .controls-overlay {
    opacity: 1;
    pointer-events: all;
  }

  /* Reducir padding de controles */
  .controls-overlay {
    padding: 10px;
  }

  /* Ajustar espaciado de botones */
  .controls-bottom {
    gap: 8px;
  }

  .volume-slider {
    width: 40px;
  }

  .control-btn {
    padding: 6px 10px;
    font-size: 12px;
    min-width: auto;
  }

  .play-btn {
    font-size: 16px;
    padding: 8px 12px;
  }

  .speed-btn {
    min-width: 50px;
    font-size: 11px;
  }

  .quality-btn {
    min-width: 55px;
    font-size: 11px;
  }

  /* Ajustar display del tiempo */
  .time-display {
    font-size: 10px;
    flex-wrap: wrap;
    gap: 5px;
  }

  .buffered-info {
    font-size: 9px;
  }

  /* Barra de progreso más visible */
  .progress-bar {
    height: 8px;
  }

  .progress-thumb {
    width: 16px;
    height: 16px;
    right: -8px;
  }

  .play-icon {
    width: 80px;
    height: 80px;
    font-size: 50px;
  }

  .quality-menu {
    right: auto;
    left: 50%;
    transform: translateX(-50%);
  }

  .quality-banner-content {
    padding: 12px 18px;
    gap: 10px;
  }

  .quality-banner-text {
    font-size: 12px;
  }

  .quality-banner-icon {
    font-size: 16px;
  }

  /* Ocultar control de volumen en móvil para ahorrar espacio */
  .volume-control {
    display: none;
  }
}
</style>
