{% extends "base.html" %}

{% block extra_head %}
<style>
  /* Ambient background */
  #ambient-bg {
    position: fixed; inset: 0; z-index: -1;
    background-size: cover; background-position: center;
    filter: blur(60px) saturate(1.8);
    opacity: 0.55;
    transition: background-image 1.2s ease, opacity 0.8s ease;
    pointer-events: none;
  }
  [data-theme="dark"] #ambient-bg { opacity: 0.75; }

  /* Progress bar */
  .progress-wrap { position: relative; }
  #progress-bar {
    -webkit-appearance: none;
    appearance: none;
    height: 3px;
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    background: linear-gradient(to right, white 0%, rgba(255,255,255,0.3) 0%);
  }
  #progress-bar::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: white;
    box-shadow: 0 1px 4px rgba(0,0,0,0.4);
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s;
  }
  .progress-wrap:hover #progress-bar::-webkit-slider-thumb { opacity: 1; }

  /* Play button press feedback */
  #btn-play:active { transform: scale(0.94); }

  /* Queue active item */
  .queue-item.active { background: rgba(99,102,241,0.08); }
  .queue-item.active .queue-title { color: rgb(99,102,241); font-weight: 600; }
  [data-theme="dark"] .queue-item.active { background: rgba(99,102,241,0.12); }

  /* Mini waveform in queue */
  .mini-wave {
    display: flex; align-items: flex-end; gap: 1.5px;
    height: 14px; width: 14px;
  }
  .mini-wave span {
    flex: 1; background: rgb(99,102,241); border-radius: 1px;
    animation: wave-bar 0.8s ease-in-out infinite;
  }
  .mini-wave span:nth-child(2) { animation-delay: 0.15s; }
  .mini-wave span:nth-child(3) { animation-delay: 0.3s; }
  .mini-wave.paused span { animation-play-state: paused; }

  /* Queue dialog */
  #queue-dialog {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    top: auto;
    width: 100%;
    max-width: 100%;
    max-height: 80vh;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 1rem 1rem 0 0;
    background: white;
    box-shadow: 0 -4px 30px rgba(0,0,0,0.15);
  }
  [data-theme="dark"] #queue-dialog {
    background: rgb(17, 24, 39);
  }
  #queue-dialog::backdrop {
    background: rgba(0,0,0,0.4);
  }
</style>
{% endblock %}

{% block content %}
<!-- Ambient background layer -->
<div id="ambient-bg"></div>

<div class="max-w-lg mx-auto px-6 min-h-[calc(100dvh-4rem)] flex flex-col justify-center gap-8">

    <!-- 封面 -->
    <div class="flex justify-center">
      <div id="cover-wrap" class="relative w-full aspect-square max-w-72 rounded-2xl overflow-hidden shadow-2xl flex items-center justify-center bg-white/10" style="contain:layout;">
        <img id="cover-img" src="" alt="封面" class="absolute inset-0 w-full h-full object-cover hidden">
        <div id="cover-wave" class="audio-waveform paused text-white/40" style="height:80px;">
          <span style="height:24px;"></span>
          <span style="height:40px;"></span>
          <span style="height:52px;"></span>
          <span style="height:40px;"></span>
          <span style="height:28px;"></span>
        </div>
      </div>
    </div>

    <!-- 曲目信息 -->
    <div class="text-center">
      <p id="track-title" class="text-lg font-semibold text-gray-800 dark:text-white truncate" style="text-shadow: 0 1px 4px rgba(255,255,255,0.4)">未选择曲目</p>
    </div>

    <!-- 进度条 -->
    <div class="progress-wrap">
      <input id="progress-bar" type="range" min="0" max="100" value="0" class="w-full">
      <div class="flex justify-between text-xs text-gray-500 dark:text-white/60 mt-1.5">
        <span id="time-current">0:00</span>
        <span id="time-total">0:00</span>
      </div>
    </div>

    <!-- 主控制栏 -->
    <div class="flex items-center justify-center gap-8">
      <button id="btn-prev" title="上一首"
        class="text-gray-500 dark:text-white/60 hover:text-gray-800 dark:hover:text-white transition-colors">
        <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="19 20 9 12 19 4 19 20"></polygon><line x1="5" y1="19" x2="5" y2="5"></line></svg>
      </button>
      <button id="btn-play"
        class="w-16 h-16 rounded-full bg-white/90 text-gray-900 flex items-center justify-center shadow-lg transition-all duration-150 hover:bg-white">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:2px"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
      </button>
      <button id="btn-next" title="下一首"
        class="text-gray-500 dark:text-white/60 hover:text-gray-800 dark:hover:text-white transition-colors">
        <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 4 15 12 5 20 5 4"></polygon><line x1="19" y1="5" x2="19" y2="19"></line></svg>
      </button>
    </div>

    <!-- 辅助控制行 -->
    <div class="flex items-center justify-center gap-3">
      <!-- 循环模式 -->
      <button id="btn-loop"
        class="text-xs font-medium flex items-center gap-1.5 px-3 py-1.5 rounded-full bg-black/8 dark:bg-white/10 text-gray-600 dark:text-white/70 hover:bg-black/15 dark:hover:bg-white/20 transition-colors">
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="17 1 21 5 17 9"></polyline><path d="M3 11V9a4 4 0 0 1 4-4h14"></path><polyline points="7 23 3 19 7 15"></polyline><path d="M21 13v2a4 4 0 0 1-4 4H3"></path></svg>
        <span id="loop-label">顺序</span>
      </button>

      <!-- 收藏 -->
      <button id="btn-fav" title="收藏"
        class="p-1.5 rounded-full text-gray-500 dark:text-white/60 hover:text-red-500 dark:hover:text-red-400 transition-colors">
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>
      </button>

      <!-- 播放列表 -->
      <button id="btn-queue" title="播放列表"
        class="p-1.5 rounded-full text-gray-500 dark:text-white/60 hover:text-gray-800 dark:hover:text-white transition-colors">
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>
      </button>

      <!-- 定时关闭 -->
      <button id="btn-sleep" title="定时关闭"
        class="p-1.5 rounded-full text-gray-500 dark:text-white/60 hover:text-gray-800 dark:hover:text-white transition-colors text-xs font-medium min-w-[2rem] text-center">
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
      </button>
    </div>

  <!-- 空态 -->
  <div id="empty-state" class="hidden text-center py-20">
    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="mx-auto text-gray-400 mb-4"><path d="M9 18V5l12-2v13"></path><circle cx="6" cy="18" r="3"></circle><circle cx="18" cy="16" r="3"></circle></svg>
    <p class="text-gray-600 dark:text-white/60">暂无音频文件</p>
    <p class="text-sm text-gray-500 dark:text-white/40 mt-1">将 MP3、FLAC、AAC 等文件放入媒体目录</p>
  </div>

</div>

<!-- 队列 Dialog -->
<dialog id="queue-dialog">
  <div class="flex flex-col h-full" style="max-height: 80vh;">
    <div class="px-4 py-3 border-b border-black/5 dark:border-white/8 flex items-center justify-between flex-shrink-0">
      <span class="text-sm font-medium text-gray-700 dark:text-gray-300">播放列表</span>
      <div class="flex items-center gap-3">
        <span id="queue-count" class="text-xs text-gray-400"></span>
        <button id="btn-close-queue" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors text-xl leading-none">&times;</button>
      </div>
    </div>
    <ul id="queue-list" class="flex-1 overflow-y-auto">
      <li class="px-4 py-8 text-center text-sm text-gray-400">加载中...</li>
    </ul>
  </div>
</dialog>
{% endblock %}

{% block extra_body %}
<script>
const POSITION_KEY = 'radio_position';
const LOOP_KEY = 'radio_loop';

let queue = [];
let currentIndex = -1;
let loopMode = localStorage.getItem(LOOP_KEY) || 'queue'; // queue | one | shuffle
let isPlaying = false;

const audio = new Audio();

// DOM refs
const ambientBg    = document.getElementById('ambient-bg');
const coverImg     = document.getElementById('cover-img');
const coverWave    = document.getElementById('cover-wave');
const trackTitle   = document.getElementById('track-title');
const progressBar  = document.getElementById('progress-bar');
const timeCurrent  = document.getElementById('time-current');
const timeTotal    = document.getElementById('time-total');
const btnPlay      = document.getElementById('btn-play');
const btnPrev      = document.getElementById('btn-prev');
const btnNext      = document.getElementById('btn-next');
const btnLoop      = document.getElementById('btn-loop');
const loopLabel    = document.getElementById('loop-label');
const btnFav       = document.getElementById('btn-fav');
const btnQueue     = document.getElementById('btn-queue');
const btnSleep     = document.getElementById('btn-sleep');
const queueDialog  = document.getElementById('queue-dialog');
const btnCloseQueue = document.getElementById('btn-close-queue');
const queueList    = document.getElementById('queue-list');
const queueCount   = document.getElementById('queue-count');
const emptyState   = document.getElementById('empty-state');

function formatTime(s) {
  if (!s || isNaN(s)) return '0:00';
  const m = Math.floor(s / 60);
  const sec = Math.floor(s % 60).toString().padStart(2, '0');
  return `${m}:${sec}`;
}

function updatePlayIcon() {
  btnPlay.innerHTML = isPlaying
    ? '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>'
    : '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:2px"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>';
}

function updateWave(playing) {
  coverWave.classList.toggle('paused', !playing);
  document.querySelectorAll('.mini-wave').forEach(w => w.classList.toggle('paused', !playing));
}

function updateAmbient(item) {
  if (item?.thumb_url) {
    ambientBg.style.backgroundImage = `url('${item.thumb_url}')`;
  }
}

function updateCover(item) {
  coverImg.onload = () => { coverImg.classList.remove('hidden'); coverWave.classList.add('hidden'); updateAmbient(item); };
  coverImg.onerror = () => { coverImg.classList.add('hidden'); coverWave.classList.remove('hidden'); };
  coverImg.src = item.thumb_url + '&v=' + Date.now();
}

function updateLoopUI() {
  const labels = { queue: '顺序', one: '单曲', shuffle: '随机' };
  loopLabel.textContent = labels[loopMode] || '顺序';
  btnLoop.classList.toggle('text-indigo-500', loopMode !== 'queue');
  btnLoop.classList.toggle('dark:text-indigo-400', loopMode !== 'queue');
}

function updateFavUI(item) {
  const filled = item.is_favorite;
  btnFav.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="${filled ? 'currentColor' : 'none'}" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="${filled ? 'text-red-500' : ''}"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>`;
}

function updateQueueHighlight(index) {
  document.querySelectorAll('.queue-item').forEach((el, i) => {
    const active = i === index;
    el.classList.toggle('active', active);
    const numEl = el.querySelector('.queue-num');
    const waveEl = el.querySelector('.mini-wave');
    if (numEl) numEl.classList.toggle('hidden', active);
    if (waveEl) waveEl.classList.toggle('hidden', !active);
    if (active) el.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
  });
}

function playAt(index) {
  if (index < 0 || index >= queue.length) return;
  currentIndex = index;
  const item = queue[index];
  audio.src = item.media_url;
  audio.play().catch(() => {});
  isPlaying = true;
  trackTitle.textContent = item.title;
  updateCover(item);
  updateFavUI(item);
  updatePlayIcon();
  updateWave(true);
  updateQueueHighlight(index);
}

function nextTrack() {
  if (!queue.length) return;
  let next;
  if (loopMode === 'one') {
    next = currentIndex;
  } else if (loopMode === 'shuffle') {
    next = Math.floor(Math.random() * queue.length);
  } else {
    next = (currentIndex + 1) % queue.length;
  }
  playAt(next);
}

function prevTrack() {
  if (!queue.length) return;
  if (audio.currentTime > 3) { audio.currentTime = 0; return; }
  const prev = loopMode === 'shuffle'
    ? Math.floor(Math.random() * queue.length)
    : (currentIndex - 1 + queue.length) % queue.length;
  playAt(prev);
}

// Audio events
audio.addEventListener('ended', nextTrack);

audio.addEventListener('timeupdate', () => {
  const pct = audio.duration ? (audio.currentTime / audio.duration) * 100 : 0;
  progressBar.value = pct;
  progressBar.style.background = `linear-gradient(to right, white ${pct}%, rgba(255,255,255,0.3) ${pct}%)`;
  timeCurrent.textContent = formatTime(audio.currentTime);
  timeTotal.textContent = formatTime(audio.duration);
});

audio.addEventListener('play',  () => { isPlaying = true;  updatePlayIcon(); updateWave(true);  });
audio.addEventListener('pause', () => {
  isPlaying = false;
  updatePlayIcon();
  updateWave(false);
  if (currentIndex >= 0) {
    localStorage.setItem(POSITION_KEY, JSON.stringify({
      name: queue[currentIndex]?.name,
      time: audio.currentTime,
    }));
  }
});

// Controls
btnPlay.addEventListener('click', () => {
  if (!queue.length) return;
  if (currentIndex < 0) { playAt(0); return; }
  isPlaying ? audio.pause() : audio.play().catch(() => {});
});

btnPrev.addEventListener('click', prevTrack);
btnNext.addEventListener('click', nextTrack);

btnLoop.addEventListener('click', () => {
  const modes = ['queue', 'one', 'shuffle'];
  loopMode = modes[(modes.indexOf(loopMode) + 1) % modes.length];
  localStorage.setItem(LOOP_KEY, loopMode);
  updateLoopUI();
});

btnFav.addEventListener('click', async () => {
  if (currentIndex < 0) return;
  const item = queue[currentIndex];
  try {
    const res = await fetch(`/api/favorite/${encodeURIComponent(item.name)}`, { method: 'POST' });
    const data = await res.json();
    item.is_favorite = data.favorite;
    updateFavUI(item);
    const qItem = document.querySelectorAll('.queue-item')[currentIndex];
    if (qItem) qItem.querySelector('.fav-dot')?.classList.toggle('hidden', !item.is_favorite);
  } catch {}
});

// Sleep timer
const SLEEP_OPTIONS = [null, 30, 60, 120];
let sleepIndex = 0;
let sleepEnd = null;
let sleepTickId = null;

const MOON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>`;

function updateSleepUI() {
  if (!sleepEnd) {
    btnSleep.innerHTML = MOON_SVG;
    btnSleep.classList.remove('text-indigo-500', 'dark:text-indigo-400');
    return;
  }
  const s = Math.ceil((sleepEnd - Date.now()) / 1000);
  const m = Math.floor(s / 60), sec = s % 60;
  btnSleep.textContent = `${m}:${sec.toString().padStart(2, '0')}`;
  btnSleep.classList.add('text-indigo-500', 'dark:text-indigo-400');
}

function tickSleep() {
  const remaining = sleepEnd - Date.now();
  if (remaining <= 0) {
    clearInterval(sleepTickId);
    sleepEnd = null;
    sleepIndex = 0;
    audio.pause();
    updateSleepUI();
    return;
  }
  updateSleepUI();
}

function setSleep(minutes) {
  clearInterval(sleepTickId);
  if (!minutes) {
    sleepEnd = null;
    updateSleepUI();
    return;
  }
  sleepEnd = Date.now() + minutes * 60000;
  sleepTickId = setInterval(tickSleep, 1000);
  updateSleepUI();
}

btnSleep.addEventListener('click', () => {
  sleepIndex = (sleepIndex + 1) % SLEEP_OPTIONS.length;
  setSleep(SLEEP_OPTIONS[sleepIndex]);
});

btnQueue.addEventListener('click', () => queueDialog.showModal());
btnCloseQueue.addEventListener('click', () => queueDialog.close());
queueDialog.addEventListener('click', e => { if (e.target === queueDialog) queueDialog.close(); });

progressBar.addEventListener('input', e => {
  audio.currentTime = (e.target.value / 100) * (audio.duration || 0);
});

// Build queue UI
function buildQueueUI() {
  if (!queue.length) {
    queueList.innerHTML = '';
    emptyState.classList.remove('hidden');
    return;
  }
  emptyState.classList.add('hidden');
  queueCount.textContent = `${queue.length} 首`;
  queueList.innerHTML = queue.map((item, i) => {
    const thumb = item.thumb_url
      ? `<img src="${item.thumb_url}" class="w-8 h-8 rounded-md object-cover flex-shrink-0" loading="lazy" onerror="this.style.display='none'">`
      : `<div class="w-8 h-8 rounded-md bg-gray-100 dark:bg-gray-700 flex-shrink-0"></div>`;
    return `
    <li class="queue-item px-3 py-2 flex items-center gap-2.5 cursor-pointer hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
        data-index="${i}">
      ${thumb}
      <div class="flex-1 min-w-0">
        <p class="queue-title text-sm text-gray-700 dark:text-gray-300 truncate">${escHtml(item.title)}</p>
      </div>
      <div class="flex items-center gap-1.5 flex-shrink-0">
        <span class="fav-dot w-1 h-1 rounded-full bg-red-400 ${item.is_favorite ? '' : 'hidden'}"></span>
        <span class="queue-num text-xs text-gray-400 w-5 text-right">${i + 1}</span>
        <span class="mini-wave hidden"><span style="height:4px"></span><span style="height:8px"></span><span style="height:10px"></span></span>
      </div>
    </li>`;
  }).join('');

  queueList.querySelectorAll('.queue-item').forEach(el => {
    el.addEventListener('click', () => {
      playAt(parseInt(el.dataset.index));
      queueDialog.close();
    });
  });
}

function escHtml(str) {
  return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

// Load and restore
async function loadQueue() {
  try {
    const res = await fetch('/api/radio/items?limit=500');
    const data = await res.json();
    queue = data.data?.items || [];
    buildQueueUI();
    updateLoopUI();

    if (!queue.length) return;

    try {
      const saved = JSON.parse(localStorage.getItem(POSITION_KEY) || '{}');
      if (saved.name) {
        const idx = queue.findIndex(i => i.name === saved.name);
        if (idx >= 0) {
          currentIndex = idx;
          const item = queue[idx];
          audio.src = item.media_url;
          trackTitle.textContent = item.title;
          updateCover(item);
          updateFavUI(item);
          updateQueueHighlight(idx);
          audio.addEventListener('loadedmetadata', () => {
            if (saved.time) audio.currentTime = saved.time;
          }, { once: true });
          return;
        }
      }
    } catch {}
  } catch {
    queueList.innerHTML = '<li class="px-4 py-8 text-center text-sm text-red-400">加载失败</li>';
  }
}

document.addEventListener('DOMContentLoaded', loadQueue);
</script>
{% endblock %}
