const state = {
  library: null,
  currentFolder: "",
  currentQueue: [],
  currentTrackIndex: -1,
  shuffle: false,
  loopMode: "list",
  albums: [],
  currentView: "home",
  activeAlbumPath: "",
};

const audio = document.getElementById("audioPlayer");
const progressBar = document.getElementById("progressBar");
const audioCacheName = "musicweb-audio-cache-v1";
let toastTimer = null;

function savePlaybackState() {
  const currentTrack = state.currentQueue[state.currentTrackIndex] || null;
  const payload = {
    currentFolder: state.currentFolder,
    currentQueue: state.currentQueue.map((track) => track.path),
    currentTrackPath: currentTrack ? currentTrack.path : "",
    currentTime: audio.currentTime || 0,
    shuffle: state.shuffle,
    loopMode: state.loopMode,
    activeAlbumPath: state.activeAlbumPath,
  };
  localStorage.setItem("musicwebplayback", JSON.stringify(payload));
}

function showIconToast(text) {
  const toast = document.getElementById("iconToast");
  toast.textContent = text;
  toast.classList.remove("is-hidden");
  if (toastTimer) clearTimeout(toastTimer);
  toastTimer = setTimeout(() => toast.classList.add("is-hidden"), 1200);
}

function restorePlaybackState() {
  const raw = localStorage.getItem("musicwebplayback");
  if (!raw || !state.library) return;

  try {
    const saved = JSON.parse(raw);
    state.shuffle = Boolean(saved.shuffle);
    state.loopMode = saved.loopMode || "list";
    state.currentFolder = saved.currentFolder || "";
    state.activeAlbumPath = saved.activeAlbumPath || "";
    updateToggleStates();
    setCurrentFolder(state.currentFolder);

    if (Array.isArray(saved.currentQueue) && saved.currentQueue.length) {
      state.currentQueue = saved.currentQueue
        .map((path) => state.library.all_tracks.find((track) => track.path === path))
        .filter(Boolean);
    }

    const trackPath = saved.currentTrackPath || "";
    if (trackPath) {
      const queueIndex = state.currentQueue.findIndex((track) => track.path === trackPath);
      if (queueIndex >= 0) {
        state.currentTrackIndex = queueIndex;
      } else {
        const single = state.library.all_tracks.find((track) => track.path === trackPath);
        if (single) {
          state.currentQueue = [single];
          state.currentTrackIndex = 0;
        }
      }
    }

    if (state.currentQueue.length && state.currentTrackIndex >= 0) {
      const track = state.currentQueue[state.currentTrackIndex];
      audio.src = track.url;
      updateDock(track);
      renderQueue();
      syncPlayButton();
      audio.addEventListener(
        "loadedmetadata",
        () => {
          audio.currentTime = Number(saved.currentTime || 0);
        },
        { once: true }
      );
    }

    if (state.activeAlbumPath) {
      renderAlbumDetail(state.activeAlbumPath);
    }
  } catch {
    localStorage.removeItem("musicwebplayback");
  }
}

async function fetchLibrary() {
  const response = await fetch("/api/library");
  state.library = await response.json();
  state.albums = buildAlbums(state.library.tree);

  document.getElementById("albumCount").textContent = state.albums.length;
  document.getElementById("trackCount").textContent = state.library.all_tracks.length;

  renderHome();
  renderPlaylists();
  restorePlaybackState();

  if (state.activeAlbumPath) {
    renderAlbumDetail(state.activeAlbumPath);
  }

  if (!state.currentQueue.length) {
    state.currentQueue = [...state.library.all_tracks];
    renderQueue();
  }
}

function buildAlbums(tree) {
  const albums = [];

  function visit(node) {
    const tracks = flattenNodeTracks(node);
    if (node.path && tracks.length) {
      albums.push({
        name: node.name || "未命名专辑",
        path: node.path,
        cover: node.cover || null,
        tracks,
      });
    }
    node.folders.forEach(visit);
  }

  visit(tree);
  return albums;
}

function flattenNodeTracks(node) {
  const tracks = [...node.tracks];
  node.folders.forEach((child) => tracks.push(...flattenNodeTracks(child)));
  return tracks;
}

function folderTracks(path) {
  const album = state.albums.find((item) => item.path === path);
  return album ? [...album.tracks] : [];
}

function setCurrentFolder(path) {
  state.currentFolder = path;
  document.getElementById("folderIndicator").textContent = path || "根目录";
}

function showView(name) {
  state.currentView = name;
  document.getElementById("homeView").classList.toggle("is-hidden", name !== "home");
  document.getElementById("detailView").classList.toggle("is-hidden", name !== "detail");
  savePlaybackState();
}

function coverLabel(name) {
  return name.length > 12 ? `${name.slice(0, 12)}...` : name;
}

function buildCoverMarkup(album, className) {
  const imageMarkup = album.cover
    ? `<img class="cover-image" src="${album.cover}" alt="${album.name}" />`
    : "";
  return `
    <div class="${className}${album.cover ? " has-cover" : ""}">
      ${imageMarkup}
      ${album.cover ? "" : `<span class="cover-name">${coverLabel(album.name)}</span>`}
    </div>
  `;
}

function renderHome() {
  const featured = [...state.albums].sort((a, b) => b.tracks.length - a.tracks.length).slice(0, 2);
  const latestTracks = [...state.library.all_tracks].slice(-8).reverse();
  const rankingAlbums = [...state.albums].sort((a, b) => b.tracks.length - a.tracks.length).slice(0, 6);

  renderFeaturedAlbums(featured);
  renderAlbumGrid(state.albums);
  renderLatestList(latestTracks);
  renderRankingList(rankingAlbums);
  renderQueue();
}

function buildAlbumCardActions(card, album) {
  const detailBtn = card.querySelector("[data-action='detail']");
  const playBtn = card.querySelector("[data-action='play']");
  detailBtn.onclick = () => renderAlbumDetail(album.path);
  playBtn.onclick = (event) => {
    event.stopPropagation();
    setCurrentFolder(album.path);
    startQueue(album.tracks, 0);
  };
  card.onclick = () => renderAlbumDetail(album.path);
}

function renderFeaturedAlbums(items) {
  const container = document.getElementById("featuredAlbums");
  container.innerHTML = "";

  if (!items.length) {
    container.innerHTML = '<div class="empty-state">暂无可展示的专辑目录</div>';
    return;
  }

  items.forEach((album) => {
    const card = document.createElement("article");
    card.className = "feature-card";
    card.innerHTML = `
      <div class="feature-card-inner">
        ${buildCoverMarkup(album, "feature-cover")}
        <div class="feature-body">
          <div>
            <h3>${album.name}</h3>
            <p class="meta-row">${album.tracks.length} 首歌曲 · ${album.path}</p>
          </div>
          <p class="subtext">点击进入详细目录页，查看歌曲列表并播放。</p>
          <div class="card-actions">
            <button class="primary-btn" data-action="detail">进入目录</button>
            <button class="secondary-btn" data-action="play">播放</button>
          </div>
        </div>
      </div>
    `;
    buildAlbumCardActions(card, album);
    container.appendChild(card);
  });
}

function renderAlbumGrid(items) {
  const container = document.getElementById("albumGrid");
  container.innerHTML = "";

  if (!items.length) {
    container.innerHTML = '<div class="empty-state">当前音乐库还没有专辑目录</div>';
    return;
  }

  items.forEach((album) => {
    const card = document.createElement("article");
    card.className = "album-card";
    card.innerHTML = `
      ${buildCoverMarkup(album, "album-cover")}
      <div class="album-body">
        <div>
          <h3>${album.name}</h3>
          <p class="meta-row">${album.tracks.length} 首歌曲</p>
        </div>
        <div class="card-actions">
          <button class="secondary-btn" data-action="detail">进入</button>
          <button class="text-btn" data-action="play">播放</button>
        </div>
      </div>
    `;
    buildAlbumCardActions(card, album);
    container.appendChild(card);
  });
}

function renderAlbumDetail(path) {
  const album = state.albums.find((item) => item.path === path);
  if (!album) return;

  state.activeAlbumPath = path;
  setCurrentFolder(path);
  showView("detail");

  document.getElementById("detailTitle").textContent = album.name;
  document.getElementById("detailMeta").textContent = `${album.path} · ${album.tracks.length} 首歌曲`;
  document.getElementById("detailTrackCount").textContent = `${album.tracks.length} 首`;

  const coverImage = document.getElementById("detailCoverImage");
  const coverFallback = document.getElementById("detailCoverFallback");
  if (album.cover) {
    coverImage.src = album.cover;
    coverImage.classList.remove("is-hidden");
    coverFallback.classList.add("is-hidden");
  } else {
    coverImage.removeAttribute("src");
    coverImage.classList.add("is-hidden");
    coverFallback.classList.remove("is-hidden");
    coverFallback.textContent = coverLabel(album.name);
  }

  document.getElementById("detailPlayBtn").onclick = () => startQueue(album.tracks, 0);
  document.getElementById("detailPlayAllBtn").onclick = () => {
    state.currentQueue = [...album.tracks, ...state.currentQueue];
    state.currentTrackIndex = 0;
    renderQueue();
    playTrack(0);
  };

  const container = document.getElementById("detailTrackList");
  container.innerHTML = "";
  album.tracks.forEach((track, index) => container.appendChild(renderTrack(track, album.tracks, index)));
}

function renderLatestList(tracks) {
  const container = document.getElementById("latestList");
  container.innerHTML = "";
  if (!tracks.length) {
    container.innerHTML = '<div class="empty-state">暂无最新更新</div>';
    return;
  }
  tracks.forEach((track, index) => container.appendChild(renderTrack(track, tracks, index)));
}

function renderRankingList(items) {
  const container = document.getElementById("rankingList");
  container.innerHTML = "";
  if (!items.length) {
    container.innerHTML = '<div class="empty-state">暂无排名数据</div>';
    return;
  }

  items.forEach((album, index) => {
    const card = document.createElement("div");
    card.className = "ranking-card";
    card.innerHTML = `
      <span class="rank-badge">${index + 1}</span>
      <div class="ranking-main">
        <h3>${album.name}</h3>
        <p class="ranking-note">${album.tracks.length} 首歌曲</p>
      </div>
      <div class="track-actions compact-actions">
        <button class="icon-btn small-icon-btn play-btn" aria-label="播放"></button>
      </div>
    `;
    card.onclick = () => renderAlbumDetail(album.path);
    card.querySelector("button").onclick = (event) => {
      event.stopPropagation();
      showIconToast("播放");
      setCurrentFolder(album.path);
      startQueue(album.tracks, 0);
    };
    container.appendChild(card);
  });
}

function renderTrack(track, sourceTracks = [track], sourceIndex = 0) {
  const template = document.getElementById("trackItemTemplate");
  const fragment = template.content.cloneNode(true);
  fragment.querySelector(".track-name").textContent = track.name;
  fragment.querySelector(".track-path").textContent = track.path;
  fragment.querySelector(".play-btn").onclick = () => {
    showIconToast("播放");
    startQueue(sourceTracks, sourceIndex);
  };
  fragment.querySelector(".queue-btn").onclick = () => {
    showIconToast("加入队列");
    state.currentQueue.push(track);
    renderQueue();
    savePlaybackState();
  };
  fragment.querySelector(".move-btn").onclick = async () => {
    showIconToast("移动歌曲");
    const destination = prompt("移动到哪个目录？输入相对 mp3file 的目录路径", track.folder || "");
    if (destination === null) return;
    await fetch("/api/move", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ source: track.path, destination_dir: destination }),
    });
    await fetchLibrary();
  };
  return fragment;
}

function renderQueue() {
  const container = document.getElementById("queueList");
  container.innerHTML = "";
  if (!state.currentQueue.length) {
    container.innerHTML = '<div class="empty-state">当前播放队列为空</div>';
    return;
  }

  state.currentQueue.forEach((track, index) => {
    const row = document.createElement("div");
    row.className = `song-row${index === state.currentTrackIndex ? " is-active" : ""}`;
    row.innerHTML = `
      <div class="song-copy">
        <strong class="track-name">${track.name}</strong>
        <p class="track-path">${track.path}</p>
      </div>
      <div class="track-actions compact-actions">
        <button class="icon-btn small-icon-btn play-btn" aria-label="播放"></button>
        <button class="icon-btn small-icon-btn move-btn" aria-label="移除"></button>
      </div>
    `;
    const [playBtn, removeBtn] = row.querySelectorAll("button");
    playBtn.onclick = () => {
      showIconToast("播放");
      playTrack(index);
    };
    removeBtn.onclick = () => {
      showIconToast("移除");
      state.currentQueue.splice(index, 1);
      if (state.currentTrackIndex >= state.currentQueue.length) {
        state.currentTrackIndex = state.currentQueue.length - 1;
      }
      renderQueue();
      savePlaybackState();
    };
    container.appendChild(row);
  });
}

function renderPlaylists() {
  const container = document.getElementById("playlistList");
  container.innerHTML = "";
  if (!state.library.playlists.length) {
    container.innerHTML = '<div class="empty-state">还没有播放列表</div>';
    return;
  }

  state.library.playlists.forEach((playlist) => {
    const item = document.createElement("div");
    item.className = "playlist-item";
    item.innerHTML = `
      <div>
        <strong>${playlist.name}</strong>
        <p>${playlist.tracks.length} 首歌曲</p>
      </div>
      <div class="track-actions compact-actions">
        <button class="icon-btn small-icon-btn play-btn" aria-label="播放"></button>
        <button class="icon-btn small-icon-btn queue-btn" aria-label="覆盖"></button>
        <button class="icon-btn small-icon-btn move-btn" aria-label="删除"></button>
      </div>
    `;

    const [playBtn, replaceBtn, deleteBtn] = item.querySelectorAll("button");
    playBtn.onclick = () => {
      showIconToast("播放列表");
      const tracks = playlist.tracks
        .map((path) => state.library.all_tracks.find((track) => track.path === path))
        .filter(Boolean);
      startQueue(tracks, 0);
    };
    replaceBtn.onclick = async () => {
      showIconToast("覆盖列表");
      await fetch(`/api/playlists/${playlist.id}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ tracks: state.currentQueue.map((track) => track.path) }),
      });
      await fetchLibrary();
    };
    deleteBtn.onclick = async () => {
      showIconToast("删除列表");
      await fetch(`/api/playlists/${playlist.id}`, { method: "DELETE" });
      await fetchLibrary();
    };
    container.appendChild(item);
  });
}

function updateToggleStates() {
  document.getElementById("shuffleBtn").classList.toggle("active", state.shuffle);
  document.getElementById("loopBtn").classList.toggle("active", state.loopMode !== "off");
  document.getElementById("loopBtn").title = `循环: ${state.loopMode === "list" ? "列表" : state.loopMode === "one" ? "单曲" : "关"}`;
  document.getElementById("shuffleBtn").title = `随机: ${state.shuffle ? "开" : "关"}`;
  document.getElementById("loopBtn").dataset.tip = state.loopMode === "list" ? "列表循环" : state.loopMode === "one" ? "单曲循环" : "循环关闭";
  document.getElementById("shuffleBtn").dataset.tip = state.shuffle ? "随机播放: 开" : "随机播放: 关";
}

function startQueue(tracks, index) {
  if (!tracks.length) return;
  state.currentQueue = [...tracks];
  state.currentTrackIndex = index;
  renderQueue();
  playTrack(index);
  savePlaybackState();
}

function updateDock(track) {
  document.getElementById("nowTitle").textContent = track.name;
  document.getElementById("nowMeta").textContent = track.path;
  document.getElementById("dockTitle").textContent = track.name;
  document.getElementById("dockPath").textContent = track.path;

  const coverImg = document.getElementById("dockCoverImage");
  const fallback = document.getElementById("dockCoverFallback");
  const album = state.albums.find((item) => item.path === track.folder) || null;
  if (album && album.cover) {
    coverImg.src = album.cover;
    coverImg.classList.remove("is-hidden");
    fallback.classList.add("is-hidden");
  } else {
    coverImg.removeAttribute("src");
    coverImg.classList.add("is-hidden");
    fallback.classList.remove("is-hidden");
    fallback.textContent = (track.name || "乐").charAt(0).toUpperCase();
  }
}

function syncPlayButton() {
  document.getElementById("playToggleBtn").classList.toggle("is-playing", !audio.paused && !audio.ended);
  document.querySelector(".icon-play").classList.toggle("is-hidden", !audio.paused && !audio.ended);
  document.querySelector(".icon-pause").classList.toggle("is-hidden", audio.paused || audio.ended);
  document.getElementById("playToggleBtn").dataset.tip = audio.paused || audio.ended ? "播放" : "暂停";
}

async function getCachedAudioUrl(track) {
  if (!("caches" in window)) return track.url;

  try {
    const cache = await caches.open(audioCacheName);
    const cached = await cache.match(track.url);
    if (cached) {
      const blob = await cached.blob();
      return URL.createObjectURL(blob);
    }

    fetch(track.url, { credentials: "same-origin" })
      .then((response) => {
        if (response.ok) cache.put(track.url, response.clone());
      })
      .catch(() => {});
  } catch {
    return track.url;
  }

  return track.url;
}

async function playTrack(index) {
  if (!state.currentQueue.length) return;
  state.currentTrackIndex = index;
  const track = state.currentQueue[index];
  audio.src = await getCachedAudioUrl(track);
  audio.play();
  updateDock(track);
  renderQueue();
  savePlaybackState();
}

function playPrevious() {
  if (!state.currentQueue.length) return;
  const prevIndex = state.currentTrackIndex > 0 ? state.currentTrackIndex - 1 : state.currentQueue.length - 1;
  playTrack(prevIndex);
}

function playNext() {
  if (!state.currentQueue.length) return;
  if (state.shuffle) {
    playTrack(Math.floor(Math.random() * state.currentQueue.length));
    return;
  }
  const nextIndex = state.currentTrackIndex + 1 < state.currentQueue.length ? state.currentTrackIndex + 1 : 0;
  playTrack(nextIndex);
}

function nextTrack() {
  if (!state.currentQueue.length) return;
  if (state.loopMode === "one") {
    playTrack(state.currentTrackIndex);
    return;
  }
  if (state.loopMode === "off" && state.currentTrackIndex === state.currentQueue.length - 1) {
    audio.pause();
    syncPlayButton();
    return;
  }
  playNext();
}

function formatTime(seconds) {
  if (!Number.isFinite(seconds)) return "00:00";
  const minutes = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
}

audio.addEventListener("ended", nextTrack);
audio.addEventListener("play", syncPlayButton);
audio.addEventListener("pause", syncPlayButton);
audio.addEventListener("timeupdate", () => {
  const progress = audio.duration ? (audio.currentTime / audio.duration) * 100 : 0;
  progressBar.value = progress;
  document.getElementById("currentTimeLabel").textContent = formatTime(audio.currentTime);
  document.getElementById("durationLabel").textContent = formatTime(audio.duration);
  savePlaybackState();
});
audio.addEventListener("loadedmetadata", () => {
  document.getElementById("durationLabel").textContent = formatTime(audio.duration);
});

progressBar.addEventListener("input", () => {
  if (!audio.duration) return;
  audio.currentTime = (Number(progressBar.value) / 100) * audio.duration;
});

document.getElementById("backHomeBtn").onclick = () => showView("home");
document.getElementById("saveQueueBtn").onclick = () => renderQueue();
document.getElementById("shuffleBtn").onclick = () => {
  state.shuffle = !state.shuffle;
  updateToggleStates();
  showIconToast(document.getElementById("shuffleBtn").dataset.tip);
  savePlaybackState();
};
document.getElementById("loopBtn").onclick = () => {
  state.loopMode = state.loopMode === "list" ? "one" : state.loopMode === "one" ? "off" : "list";
  updateToggleStates();
  showIconToast(document.getElementById("loopBtn").dataset.tip);
  savePlaybackState();
};
document.getElementById("prevBtn").onclick = () => {
  showIconToast("上一曲");
  playPrevious();
};
document.getElementById("nextBtn").onclick = () => {
  showIconToast("下一曲");
  playNext();
};
document.getElementById("playToggleBtn").onclick = () => {
  if (!state.currentQueue.length && state.library?.all_tracks?.length) {
    startQueue(state.library.all_tracks, 0);
    showIconToast("开始播放");
    return;
  }
  if (audio.paused) {
    audio.play();
    showIconToast("播放");
  } else {
    audio.pause();
    showIconToast("暂停");
  }
};

document.getElementById("uploadBtn").onclick = async () => {
  const files = document.getElementById("uploadInput").files;
  if (!files.length) {
    alert("请选择文件");
    return;
  }
  const formData = new FormData();
  Array.from(files).forEach((file) => formData.append("files", file));
  formData.append("target_dir", document.getElementById("targetDir").value.trim());
  await fetch("/api/upload", { method: "POST", body: formData });
  document.getElementById("uploadInput").value = "";
  await fetchLibrary();
};

document.getElementById("createFolderBtn").onclick = async () => {
  const path = document.getElementById("newFolderInput").value.trim();
  if (!path) {
    alert("请输入目录名");
    return;
  }
  await fetch("/api/folder", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ path }),
  });
  document.getElementById("newFolderInput").value = "";
  await fetchLibrary();
};

document.getElementById("createPlaylistBtn").onclick = async () => {
  const name = document.getElementById("playlistNameInput").value.trim();
  if (!name) {
    alert("请输入播放列表名称");
    return;
  }
  await fetch("/api/playlists", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name, tracks: state.currentQueue.map((track) => track.path) }),
  });
  document.getElementById("playlistNameInput").value = "";
  await fetchLibrary();
};

updateToggleStates();
fetchLibrary();
