const listEl = document.getElementById("tts-list");
const textInput = document.getElementById("text-input");
const saveBtn = document.getElementById("save-btn");
const voiceSelect = document.getElementById("voice-select");
const editBtn = document.getElementById("edit-btn");
const deleteBtn = document.getElementById("delete-btn");
const cancelBtn = document.getElementById("cancel-btn");
const downloadLink = document.getElementById("download-link");
const progressWrap = document.getElementById("save-progress");
const progressBar = document.getElementById("save-progress-bar");

let items = [];
let editMode = false;
const selectedIds = new Set();
let progressTimer = null;
let selectedItemId = null;
let selectedDownloadUrl = null;

function startProgress() {
  let value = 0;
  progressWrap.classList.remove("hidden");
  progressBar.style.width = "0%";
  progressBar.setAttribute("aria-valuenow", "0");

  if (progressTimer) {
    clearInterval(progressTimer);
  }

  progressTimer = setInterval(() => {
    value = Math.min(value + Math.random() * 8 + 2, 90);
    progressBar.style.width = `${value}%`;
    progressBar.setAttribute("aria-valuenow", `${Math.round(value)}`);
  }, 300);
}

function finishProgress(success = true) {
  if (progressTimer) {
    clearInterval(progressTimer);
    progressTimer = null;
  }

  progressBar.style.width = "100%";
  progressBar.setAttribute("aria-valuenow", "100");

  const delay = success ? 400 : 1200;
  setTimeout(() => {
    progressBar.style.width = "0%";
    progressBar.setAttribute("aria-valuenow", "0");
    progressWrap.classList.add("hidden");
  }, delay);
}

function setEditMode(isEdit) {
  editMode = isEdit;
  selectedIds.clear();
  selectedItemId = null;
  selectedDownloadUrl = null;
  editBtn.classList.toggle("hidden", editMode);
  deleteBtn.classList.toggle("hidden", !editMode);
  cancelBtn.classList.toggle("hidden", !editMode);
  downloadLink.classList.add("hidden");
  downloadLink.href = "#";
  renderList();
}

function renderList() {
  listEl.innerHTML = "";
  items.forEach((item) => {
    const li = document.createElement("li");
    li.className = "tts-item";
    if (!editMode && selectedItemId === item.id) {
      li.classList.add("selected");
    }

    if (editMode) {
      const checkbox = document.createElement("input");
      checkbox.type = "checkbox";
      checkbox.checked = selectedIds.has(item.id);
      checkbox.addEventListener("click", (event) => {
        event.stopPropagation();
        if (checkbox.checked) {
          selectedIds.add(item.id);
        } else {
          selectedIds.delete(item.id);
        }
      });
      li.appendChild(checkbox);
    } else {
      const bullet = document.createElement("span");
      bullet.textContent = "•";
      bullet.className = "bullet";
      li.appendChild(bullet);
    }

    const label = document.createElement("span");
    label.textContent = item.size_display
      ? `${item.display_time} (${item.size_display})`
      : item.display_time;
    label.className = "item-label";
    li.appendChild(label);

    li.addEventListener("click", () => handleItemClick(item));
    listEl.appendChild(li);
  });
}

async function loadList() {
  const res = await fetch("/api/tts");
  items = await res.json();
  renderList();
}

async function handleSave() {
  const text = (textInput.value || "").trim();
  const voice = (voiceSelect?.value || "male").trim();
  if (text.length < 11) {
    alert("10개 글자 이상이어야 합니다");
    return;
  }

  startProgress();
  const res = await fetch("/api/tts", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text, voice }),
  });

  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    alert(err.detail || "저장에 실패했습니다.");
    finishProgress(false);
    return;
  }

  const created = await res.json();
  items.unshift(created);
  renderList();
  finishProgress(true);
}

async function handleItemClick(item) {
  if (editMode) {
    if (selectedIds.has(item.id)) {
      selectedIds.delete(item.id);
    } else {
      selectedIds.add(item.id);
    }
    renderList();
    return;
  }

  if (selectedItemId === item.id) {
    selectedItemId = null;
    selectedDownloadUrl = null;
    downloadLink.href = "#";
    downloadLink.classList.add("hidden");
    renderList();
    return;
  }

  const res = await fetch(`/api/tts/${item.id}`);
  if (!res.ok) {
    alert("항목을 불러오지 못했습니다.");
    return;
  }

  const data = await res.json();
  textInput.value = data.text || "";
  selectedItemId = item.id;
  selectedDownloadUrl = data.download_url;
  downloadLink.href = selectedDownloadUrl;
  downloadLink.classList.remove("hidden");
  renderList();
}

async function handleDelete() {
  const ids = Array.from(selectedIds);
  if (ids.length === 0) {
    alert("삭제할 항목을 선택하세요.");
    return;
  }

  const res = await fetch("/api/tts", {
    method: "DELETE",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ ids }),
  });

  if (!res.ok) {
    alert("삭제에 실패했습니다.");
    return;
  }

  const data = await res.json();
  const deletedSet = new Set(data.deleted || []);
  items = items.filter((item) => !deletedSet.has(item.id));
  textInput.value = "";
  selectedItemId = null;
  selectedDownloadUrl = null;
  downloadLink.href = "#";
  downloadLink.classList.add("hidden");
  setEditMode(false);
}

saveBtn.addEventListener("click", handleSave);
editBtn.addEventListener("click", () => setEditMode(true));
cancelBtn.addEventListener("click", () => setEditMode(false));
deleteBtn.addEventListener("click", handleDelete);
downloadLink.addEventListener("click", (event) => {
  if (!selectedDownloadUrl) {
    event.preventDefault();
    alert("다운로드할 항목을 선택하세요.");
  }
});

loadList();
