import { api, adminApi } from "./js/api.js";
import { t, setLanguage, getLanguage, initI18n, onLanguageChange } from "./js/i18n.js";
import { state, clearUserState, getSavedUsername, setSavedUsername } from "./js/state.js";
import { $, toast } from "./js/dom.js";
import {
  setAuthUI,
  setAuthMode,
  handleAuthError,
  renderWelcome,
  renderPhasePill,
  renderCounts,
  renderMySuggestions,
  renderAllSuggestions,
  renderVotes,
  syncVoteScores,
  renderResults,
  renderPhaseTitles,
  openNewSuggestionModal,
  updatePhaseNav,
  openConfirmModal,
} from "./js/ui.js";
import {
  loadState,
  loadSuggestData,
  loadRevealData,
  loadVoteData,
  loadResults,
  refreshPhaseData,
} from "./js/data.js";

initI18n();

function setupHandlers() {
  const toggleAuth = $("auth-toggle");
  if (toggleAuth) {
    toggleAuth.addEventListener("click", (e) => {
      e.preventDefault();
      setAuthMode(state.authMode === "login" ? "register" : "login");
    });
  }
  setAuthMode(state.authMode);

  const loginUser = $("login-username");
  if (loginUser) {
    const markEditing = () => { loginUser.dataset.userEditing = "1"; };
    ["focus", "input", "keydown"].forEach((evt) => loginUser.addEventListener(evt, markEditing));
    loginUser.addEventListener("blur", () => { delete loginUser.dataset.userEditing; });
  }

  setupLanguageSwitchers();

  onLanguageChange(() => {
    updateLanguageButtons();
    renderWelcome();
    renderPhasePill();
    renderCounts();
    renderPhaseTitles();
    renderMySuggestions();
    renderAllSuggestions();
    if (state.phase === "Vote") {
      renderVotes();
      state.votesRendered = true;
      syncVoteScores();
    }
    if (state.phase === "Results") {
      renderResults();
    }
    updatePhaseNav();
  });

  const loginForm = $("login-form");
  if (loginForm) {
    loginForm.addEventListener("submit", async (e) => {
      e.preventDefault();
      const username = $("login-username").value.trim();
      const password = $("login-password").value;
      if (username.length > 24) return toast("Username must be 24 characters or fewer.", true);
      if (!username || !password) return toast(t("auth.needCredentials"), true);
      try {
        await api.login({ username, password });
        setSavedUsername(username);
        state.isAuthenticated = true;
        setAuthUI(true);
        await refreshPhaseData();
        toast(t("toast.loggedIn"));
      } catch (err) {
        if (err?.status === 401) return toast(t("auth.invalidCredentials"), true);
        if (handleAuthError(err, clearUserState)) return;
      }
    });
  }

  const registerForm = $("register-form");
  if (registerForm) {
    registerForm.addEventListener("submit", async (e) => {
      e.preventDefault();
      const username = $("register-username").value.trim();
      const password = $("register-password").value;
      const displayName = $("register-displayName").value.trim();
      const adminKey = $("register-adminkey").value.trim();
      if (!displayName) return toast(t("toast.displayNameRequired") || "Display name is required.", true);
      if (username.length > 24) return toast("Username must be 24 characters or fewer.", true);
      if (displayName.length > 16) return toast("Display name must be 16 characters or fewer.", true);
      if (!username || !password) return toast(t("auth.needCredentials"), true);
      try {
        await api.register({ username, password, displayName, adminKey });
        setSavedUsername(username);
        state.isAuthenticated = true;
        setAuthUI(true);
        await refreshPhaseData();
        toast(t("toast.registered"));
      } catch (err) {
        if (handleAuthError(err, clearUserState)) return;
        toast(err.message, true);
      }
    });
  }

  const openSuggestBtn = $("open-suggest-modal");
  if (openSuggestBtn) {
    openSuggestBtn.addEventListener("click", (e) => {
      e.preventDefault();
      if (state.phase !== "Suggest") return;
      openNewSuggestionModal();
    });
  }
  const openJokerBtn = $("open-joker-modal");
  if (openJokerBtn) {
    openJokerBtn.addEventListener("click", (e) => {
      e.preventDefault();
      if (state.phase !== "Vote" || !state.hasJoker) return;
      openNewSuggestionModal();
    });
  }

  bindNavButtons();

  $("reset").addEventListener("click", () => adminAction(adminApi.reset, t("admin.resetDone")));
  $("factory-reset").addEventListener("click", () => adminAction(adminApi.factoryReset, t("admin.factoryResetDone")));

  const logoutBtn = $("logout");
  if (logoutBtn) {
    logoutBtn.addEventListener("click", async (e) => {
      e.preventDefault();
      const lastUser = state.me?.username;
      try {
        await api.logout();
      } catch (err) {
        toast(err.message, true);
      }
      clearUserState();
      state.isAuthenticated = false;
      setAuthUI(false);
      if (lastUser) {
        setSavedUsername(lastUser);
        const loginUser = $("login-username");
        if (loginUser) loginUser.value = lastUser;
        const loginPass = $("login-password");
        if (loginPass) loginPass.value = "";
      }
    });
  }

  const adminToggle = $("admin-toggle");
  const adminCard = $("admin-card");
  const adminClose = $("admin-close");
  if (adminToggle && adminCard && adminClose) {
    const togglePanel = (show) => adminCard.classList.toggle("hidden", !show);
    adminToggle.addEventListener("click", () => togglePanel(adminCard.classList.contains("hidden")));
    adminClose.addEventListener("click", () => togglePanel(false));
  }

  const resultsToggle = $("results-open");
  if (resultsToggle) {
    resultsToggle.addEventListener("change", async (e) => {
      const desired = !!e.target.checked;
      try {
        const resp = await adminApi.setResultsOpen(desired);
        state.resultsOpen = resp.resultsOpen;
        renderPhasePill();
        toast(t("admin.resultsUpdated"));
      } catch (err) {
        e.target.checked = !desired;
        toast(err.message, true);
      }
    });
  }

  const linkApply = $("link-apply");
  if (linkApply) {
    linkApply.addEventListener("click", async () => {
      const source = Number($("link-source")?.value);
      const target = Number($("link-target")?.value);
      if (!source || !target || source === target) {
        return toast(t("admin.linkValidation"), true);
      }
      try {
        await adminApi.linkSuggestions(source, target);
        toast(t("admin.linkDone"));
        await refreshPhaseData();
      } catch (err) {
        toast(err.message, true);
      }
    });
  }

  const playerTable = $("admin-player-table");
  if (playerTable) {
    playerTable.addEventListener("click", async (e) => {
      const grantBtn = e.target.closest("[data-grant-joker]");
      const deleteBtn = e.target.closest("[data-delete-player]");
      if (grantBtn) {
        const playerId = grantBtn.dataset.grantJoker;
        try {
          await adminApi.grantJoker(playerId);
          toast(t("admin.jokerGranted"));
          await refreshPhaseData();
        } catch (err) {
          toast(err.message, true);
        }
      } else if (deleteBtn) {
        const playerId = deleteBtn.dataset.deletePlayer;
        const name = deleteBtn.dataset.name || "";
        openConfirmModal({
          title: t("admin.deleteTitle"),
          body: t("admin.deleteBody", { name }),
          confirmLabel: t("admin.deleteConfirm"),
          onConfirm: async (close) => {
            try {
              await adminApi.deletePlayer(playerId);
              toast(t("admin.deleteDone"));
              close();
              await refreshPhaseData();
            } catch (err) {
              toast(err.message, true);
            }
          },
        });
      }
    });
  }
}

async function adminAction(fn, successMessage) {
  try {
    await fn();
    toast(successMessage);
    await refreshPhaseData();
  } catch (err) {
    toast(err.message, true);
  }
}

async function main() {
  setupHandlers();
  try {
    await refreshPhaseData();
  } catch (err) {
    toast(err.message, true);
  }
  setInterval(() => {
    refreshPhaseData().catch((err) => {
      if (!handleAuthError(err, clearUserState)) toast(err.message, true);
    });
  }, 4000);
}

main();

function updateLanguageButtons() {
  document.querySelectorAll(".lang-button").forEach((btn) => {
    btn.textContent = "🌐";
    btn.title = t("lang.label");
    btn.setAttribute("aria-label", t("lang.label"));
  });
}

function setupLanguageSwitchers() {
  const switches = document.querySelectorAll(".lang-switch");
  const closeAll = () =>
    switches.forEach((wrap) => wrap.querySelector(".lang-menu")?.classList.add("hidden"));

  switches.forEach((wrap) => {
    const btn = wrap.querySelector(".lang-button");
    const menu = wrap.querySelector(".lang-menu");
    if (!btn || !menu) return;
    btn.addEventListener("click", (e) => {
      e.preventDefault();
      const isHidden = menu.classList.contains("hidden");
      closeAll();
      if (isHidden) menu.classList.remove("hidden");
    });
    menu.querySelectorAll("[data-lang]").forEach((item) =>
      item.addEventListener("click", () => {
        const lang = item.dataset.lang;
        if (lang) setLanguage(lang);
        closeAll();
      }),
    );
  });

  document.addEventListener("click", (e) => {
    if (!e.target.closest(".lang-switch")) closeAll();
  });

  updateLanguageButtons();
}

function bindNavButtons() {
  const makeForward = (id, before) => {
    const btn = $(id);
    if (!btn) return;
    btn.addEventListener("click", async () => {
      try {
        if (before) {
          const proceed = await before();
          if (!proceed) return;
        }
        const resp = await api.nextPhase();
        state.prevPhase = state.phase;
        state.phase = resp.currentPhase;
        state.resultsOpen = resp.resultsOpen ?? state.resultsOpen;
        state.votesRendered = false;
        renderPhasePill();
        await refreshPhaseData();
      } catch (err) {
        toast(err.message, true);
      }
    });
  };

  const makeBack = (id) => {
    const btn = $(id);
    if (!btn) return;
    btn.addEventListener("click", async () => {
      try {
        const resp = await api.prevPhase();
        state.prevPhase = state.phase;
        state.phase = resp.currentPhase;
        state.resultsOpen = resp.resultsOpen ?? state.resultsOpen;
        state.votesRendered = false;
        renderPhasePill();
        await refreshPhaseData();
      } catch (err) {
        toast(err.message, true);
      }
    });
  };

  makeForward("nav-suggest-next", async () => {
    return await new Promise((resolve) => {
      openConfirmModal({
        title: t("nav.freezeModalTitle"),
        body: t("nav.freezeModalBody"),
        confirmLabel: t("nav.next"),
        onConfirm: (close) => {
          close();
          resolve(true);
        },
      });
    });
  });
  makeBack("nav-vote-prev");

  const finalizeBtn = $("finalize-votes");
  if (finalizeBtn) {
    finalizeBtn.addEventListener("click", async () => {
      try {
        const desired = !state.votesFinal;
        await api.finalizeVotes(desired);
        state.votesFinal = desired;
        renderPhasePill();
        renderVotes();
        toast(desired ? t("vote.finalize") : t("vote.unfinalize"));
      } catch (err) {
        toast(err.message, true);
      }
    });
  }
}
