import { mountWespLogoLoader } from "/static/js/wesp-logo-loader.js?v=6";
import {
  markLoginTransition,
  storePreloadedApiPayload,
  PRELOAD_FEED_DISPENSERS_KEY,
} from "/static/js/wesp-nav-preload.js";

const LS_LOGIN = "wesp_saved_login";
const LS_REMEMBER = "wesp_remember_login";
const THEME_STORAGE_KEY = "theme";
const POST_LOGIN_REDIRECT_DELAY_MS = 300;
/** Длительность анимации логотипа после успешного входа (на странице login). */
const LOGIN_EXIT_ANIM_MS = 3500;

const RECIPES_WARM_URLS = [
  "/recipes",
  "/static/css/bootstrap.min.css",
  "/static/css/wesp-zootech-shell.css",
  "/static/css/wesp-zootech-layout.css",
  "/static/css/wesp-zootech-components.css",
  "/static/css/wesp-recipes-skeleton.css",
  "/static/css/wesp-logo-loader.css",
  "/static/css/notyf.min.css",
  "/static/css/font-awesome.min.css",
  "/static/js/wesp-theme-boot.js",
  "/static/js/wesp-logo-loader.js?v=6",
  "/static/js/wesp-page-enter.js",
  "/static/js/wesp-nav-logo-shimmer.js",
  "/static/js/wesp-zootech-nav.js",
  "/static/js/notyf.min.js",
  "/static/js/bootstrap.bundle.min.js",
  "/static/js/wesp-dialog.js",
  "/static/js/pages/recipes-page.js",
  "/static/js/pages/recipes-auth-settings.js",
  "/static/js/pages/recipes-data-controller.js",
  "/static/js/pages/recipes-operations-controller.js",
  "/static/js/pages/recipes-editor-controller.js",
  "/static/js/modules/app-state.js",
];

function delay(ms) {
  return new Promise((resolve) => window.setTimeout(resolve, ms));
}

function preloadUrl(url) {
  return fetch(url, { credentials: "same-origin" }).catch(() => null);
}

async function preloadRecipesAfterLogin() {
  markLoginTransition();

  const apiTask = preloadUrl("/api/feed_dispensers").then(async (response) => {
    if (!response?.ok) return;
    const payload = await response.json();
    if (Array.isArray(payload)) {
      storePreloadedApiPayload(PRELOAD_FEED_DISPENSERS_KEY, payload);
    }
  });

  await Promise.allSettled([
    apiTask,
    ...RECIPES_WARM_URLS.map((url) => preloadUrl(url)),
  ]);
}

async function finishLoginTransition(target) {
  const preloadPromise = preloadRecipesAfterLogin();
  await playLoginExitAnimation();
  await Promise.all([preloadPromise, delay(POST_LOGIN_REDIRECT_DELAY_MS)]);
}

function themeForLogoLoader() {
  try {
    const saved = (localStorage.getItem(THEME_STORAGE_KEY) || "").trim().toLowerCase();
    if (saved === "light" || saved === "organic" || saved === "dark") return saved;
  } catch {
    /* ignore */
  }
  const attr = document.documentElement.getAttribute("data-theme");
  if (attr === "light" || attr === "organic" || attr === "dark") return attr;
  return "dark";
}

function isDarkTheme() {
  return themeForLogoLoader() === "dark";
}

function safeNextPath(raw) {
  if (raw == null || typeof raw !== "string") return null;
  const s = raw.trim();
  if (!s || s.charAt(0) !== "/") return null;
  if (s.indexOf("//") === 0) return null;
  if (s.indexOf("://") !== -1) return null;
  if (s.indexOf("\0") !== -1 || s.indexOf("\r") !== -1 || s.indexOf("\n") !== -1) return null;
  const pathOnly = s.split("?", 1)[0];
  if (pathOnly.indexOf("@") !== -1) return null;
  return s;
}

function postLoginRedirectUrl() {
  try {
    const params = new URLSearchParams(window.location.search);
    const n = safeNextPath(params.get("next"));
    if (n) return n;
  } catch (e) {
    /* ignore */
  }
  return "/recipes";
}

function showError(message) {
  const errorDiv = document.getElementById("errorMessage");
  if (!errorDiv) return;
  errorDiv.textContent = message;
  errorDiv.style.display = "block";
  window.setTimeout(() => {
    errorDiv.style.display = "none";
  }, 5000);
}

function setLoading(loading) {
  const button = document.getElementById("authButton");
  const buttonText = document.getElementById("buttonText");
  const spinner = document.getElementById("loadingSpinner");
  const loginInput = document.getElementById("loginInput");
  const passwordInput = document.getElementById("passwordInput");
  const rememberInput = document.getElementById("rememberInput");

  if (button) button.disabled = loading;
  if (loginInput) loginInput.disabled = loading;
  if (passwordInput) passwordInput.disabled = loading;
  if (rememberInput) rememberInput.disabled = loading;

  if (buttonText && spinner) {
    buttonText.style.display = loading ? "none" : "block";
    spinner.style.display = loading ? "block" : "none";
  }
}

function applyRememberToStorage(login, remember) {
  if (remember) {
    try {
      localStorage.setItem(LS_LOGIN, login);
      localStorage.setItem(LS_REMEMBER, "1");
    } catch (e) {
      /* ignore */
    }
  } else {
    try {
      localStorage.removeItem(LS_LOGIN);
      localStorage.removeItem(LS_REMEMBER);
    } catch (e) {
      /* ignore */
    }
  }
}

function loadRememberFromStorage() {
  try {
    if (localStorage.getItem(LS_REMEMBER) === "1") {
      const saved = localStorage.getItem(LS_LOGIN);
      if (saved) {
        const loginInput = document.getElementById("loginInput");
        const rememberInput = document.getElementById("rememberInput");
        if (loginInput) loginInput.value = saved;
        if (rememberInput) rememberInput.checked = true;
      }
    }
  } catch (e) {
    /* ignore */
  }
}

async function checkSession() {
  try {
    const r = await fetch("/api/auth/check", { credentials: "same-origin" });
    const data = await r.json();
    if (data.authenticated && data.remember_login) {
      const target = postLoginRedirectUrl();
      await finishLoginTransition(target);
      window.location.href = target;
    }
  } catch (e) {
    /* stay on login */
  }
}

function playLoginExitAnimation() {
  return new Promise((resolve) => {
    const page = document.querySelector(".z-login-page");
    if (page) page.classList.add("z-login-page--hidden");

    const backdrop = document.createElement("div");
    backdrop.className = "z-login-backdrop";
    document.body.appendChild(backdrop);

    const wrap = document.createElement("div");
    wrap.className = "z-login-loader";
    const root = document.createElement("div");
    wrap.appendChild(root);
    document.body.appendChild(wrap);

    mountWespLogoLoader(root, {
      loop: false,
      durationMs: LOGIN_EXIT_ANIM_MS,
      totalDurationMs: LOGIN_EXIT_ANIM_MS,
      embedded: true,
      transparentBackground: true,
      knockoutBackground: true,
      theme: themeForLogoLoader(),
      onComplete: () => resolve(),
    }).catch(() => resolve());
  });
}

async function authenticate(event) {
  event.preventDefault();

  const login = document.getElementById("loginInput")?.value?.trim() || "";
  const password = document.getElementById("passwordInput")?.value || "";
  const remember = !!document.getElementById("rememberInput")?.checked;

  if (!login) {
    showError("Введите логин");
    return;
  }
  if (!password) {
    showError("Введите пароль");
    return;
  }

  setLoading(true);

  try {
    const response = await fetch("/api/auth/login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "same-origin",
      body: JSON.stringify({ login, password, remember }),
    });

    const data = await response.json();

    if (data.status === "success") {
      applyRememberToStorage(login, remember);
      const target = postLoginRedirectUrl();
      await finishLoginTransition(target);
      window.location.href = target;
      return;
    }

    showError(data.message || "Неверный логин или пароль");
    const passwordInput = document.getElementById("passwordInput");
    if (passwordInput) {
      passwordInput.value = "";
      passwordInput.focus();
    }
    setLoading(false);
  } catch (error) {
    showError("Ошибка соединения. Попробуйте снова.");
    console.error("Authentication error:", error);
    setLoading(false);
  }
}

function initLoginPage() {
  loadRememberFromStorage();
  checkSession();
  document.getElementById("loginInput")?.focus();

  document.getElementById("loginForm")?.addEventListener("submit", authenticate);
  document.getElementById("loginInput")?.addEventListener("keypress", (e) => {
    if (e.key === "Enter") document.getElementById("passwordInput")?.focus();
  });
  document.getElementById("passwordInput")?.addEventListener("keypress", (e) => {
    if (e.key === "Enter") authenticate(e);
  });
}

if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", initLoginPage);
} else {
  initLoginPage();
}
