import { initThemePicker, initHighContrastToggle, initThemeToggle, applyTheme, getTheme } from "/static/js/wesp-theme.js";
import {
  DEFAULT_PASSWORD_MIN_LEN,
  validateCredentialChange,
} from "/static/js/wesp-user-credentials.js";

export function createRecipesAuthSettingsController({ notyf }) {
  let settingsModalClickHandler = null;
  let settingsEscapeHandler = null;
  let syncDispenserNames = [];
  let passwordMinLen = DEFAULT_PASSWORD_MIN_LEN;

  function escapeHtmlSyncSettings(value) {
    if (value == null) return "";
    const div = document.createElement("div");
    div.textContent = String(value);
    return div.innerHTML;
  }

  function closeSettings() {
    const modal = document.getElementById("settingsModal");
    if (!modal) return;

    modal.style.display = "none";
    document.body.style.overflow = "";

    const form = document.getElementById("settingsForm");
    if (form) form.reset();

    const credForm = document.getElementById("credentialsForm");
    if (credForm) credForm.style.display = "none";
    const userCard = document.querySelector(".settings-user-card--clickable");
    if (userCard) userCard.classList.remove("open");

    const syncForm = document.getElementById("syncSettingsForm");
    if (syncForm) syncForm.style.display = "none";
    const syncCard = document.querySelector(".settings-sync-card--clickable");
    if (syncCard) syncCard.classList.remove("open");

    if (settingsModalClickHandler) {
      modal.removeEventListener("click", settingsModalClickHandler);
      settingsModalClickHandler = null;
    }
    if (settingsEscapeHandler) {
      document.removeEventListener("keydown", settingsEscapeHandler);
      settingsEscapeHandler = null;
    }
  }

  async function openSettings(event) {
    if (event) event.preventDefault();

    try {
      const response = await fetch("/api/auth/get_current_credentials");
      const data = await response.json();
      if (data.status === "success") {
        const oldLogin = document.getElementById("oldLogin");
        const oldPassword = document.getElementById("oldPassword");
        if (oldLogin) oldLogin.value = data.login || "";
        if (oldPassword) oldPassword.value = "";
      }
    } catch (error) {
      console.error("Ошибка загрузки текущих учетных данных:", error);
    }

    const modal = document.getElementById("settingsModal");
    if (!modal) return;
    modal.style.display = "block";
    document.body.style.overflow = "hidden";
    initThemePicker();
    initHighContrastToggle();

    if (settingsModalClickHandler) {
      modal.removeEventListener("click", settingsModalClickHandler);
    }
    if (settingsEscapeHandler) {
      document.removeEventListener("keydown", settingsEscapeHandler);
    }

    settingsModalClickHandler = (e) => {
      if (e.target === modal) closeSettings();
    };
    settingsEscapeHandler = (e) => {
      if (e.key === "Escape" && modal.style.display === "block") closeSettings();
    };

    modal.addEventListener("click", settingsModalClickHandler);
    document.addEventListener("keydown", settingsEscapeHandler);
  }

  async function checkAuth() {
    try {
      const response = await fetch("/api/auth/check");
      const data = await response.json();
      if (data.status === "success" && data.authenticated) {
        const userInfo = document.getElementById("userInfo");
        const userLogin = document.getElementById("userLogin");
        const mobileUserInfo = document.getElementById("mobileUserInfo");
        const canOpenAdmin = Boolean(data.is_superuser);
        window.WESP_CAN_LAB = Boolean(data.can_lab);
        window.WespLabAccess?.apply?.(window.WESP_CAN_LAB);
        const rules = data.user_rules || {};
        passwordMinLen = Number(rules.password_min_len) || DEFAULT_PASSWORD_MIN_LEN;
        if (userLogin) userLogin.textContent = data.user_login;
        if (userInfo) {
          userInfo.style.cursor = canOpenAdmin ? "pointer" : "";
          userInfo.title = canOpenAdmin ? "Открыть админ-панель" : "";
          userInfo.onclick = canOpenAdmin
            ? () => {
                window.location.href = "/admin";
              }
            : null;
        }
        if (mobileUserInfo) {
          mobileUserInfo.innerHTML = `<i class="fas fa-user"></i> ${data.user_login}`;
          mobileUserInfo.style.cursor = canOpenAdmin ? "pointer" : "";
          mobileUserInfo.title = canOpenAdmin ? "Открыть админ-панель" : "";
          mobileUserInfo.onclick = canOpenAdmin
            ? () => {
                window.location.href = "/admin";
              }
            : null;
        }
      } else {
        window.location.href = "/login";
      }
      return data;
    } catch (error) {
      console.error("Ошибка проверки авторизации:", error);
      window.location.href = "/login";
      return null;
    }
  }

  async function logout() {
    try {
      const response = await fetch("/api/auth/logout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const data = await response.json();
      if (data.status === "success") {
        window.location.href = "/";
      } else {
        notyf.error("Ошибка при выходе из системы");
      }
    } catch (error) {
      console.error("Ошибка при выходе:", error);
      notyf.error("Ошибка при выходе из системы");
    }
  }

  function setupMobileMenu() {
    const mobileUserInfo = document.getElementById("mobileUserInfo");
    const userInfo = document.getElementById("userInfo");
    if (userInfo && mobileUserInfo) {
      mobileUserInfo.textContent = userInfo.textContent?.trim() || "";
    }
  }

  async function loadSyncClientsSettings() {
    const listEl = document.getElementById("syncClientsListSettings");
    const emptyEl = document.getElementById("syncClientsEmptySettings");
    if (!listEl) return;

    listEl.innerHTML = "";
    if (emptyEl) emptyEl.style.display = "none";

    try {
      const [clientsRes, namesRes] = await Promise.all([
        fetch("/api/sync/clients"),
        fetch("/api/feed_dispensers/names"),
      ]);
      const clients = clientsRes.ok ? await clientsRes.json() : [];
      syncDispenserNames = namesRes.ok ? await namesRes.json() : [];

      if (!clients || clients.length === 0) {
        if (emptyEl) {
          emptyEl.style.display = "block";
          emptyEl.textContent = "Нет подключенных клиентов";
        }
        return;
      }

      clients.forEach((client) => {
        const displayLabel = client.display_name || client.client_name || client.node_id;
        const item = document.createElement("div");
        item.className = "settings-sync-client-item";
        item.dataset.nodeId = client.node_id;
        item.dataset.displayName = displayLabel || "";
        item.innerHTML =
          `<span class="settings-sync-client-name">${escapeHtmlSyncSettings(displayLabel)}</span>` +
          '<div class="settings-sync-client-actions">' +
          '<button type="button" class="btn btn-sm btn-edit btn-outline-primary" data-action="sync-edit-client"><i class="fas fa-edit"></i> Изменить</button> ' +
          '<button type="button" class="btn btn-sm btn-delete btn-outline-danger" data-action="sync-delete-client"><i class="fas fa-trash"></i> Удалить</button>' +
          "</div>";
        listEl.appendChild(item);
      });
    } catch (error) {
      if (emptyEl) {
        emptyEl.style.display = "block";
        emptyEl.textContent = "Не удалось загрузить список клиентов";
      }
    }
  }

  function editSyncClientSettings(btn) {
    const item = btn && btn.closest ? btn.closest(".settings-sync-client-item") : null;
    const nodeId = item ? item.dataset.nodeId : null;
    const currentName = item ? item.dataset.displayName || "" : "";
    if (!item || !nodeId) return;

    let selectHtml = '<option value="">— не задано —</option>';
    syncDispenserNames.forEach((name) => {
      const escaped = escapeHtmlSyncSettings(name);
      selectHtml += `<option value="${escaped}">${escaped}</option>`;
    });

    item.innerHTML =
      '<div class="settings-sync-edit-row w-100">' +
      '<label class="mb-0 me-2">Имя клиента:</label>' +
      `<select class="form-control form-control-sm d-inline-block" id="syncEditSelect_${nodeId}">${selectHtml}</select> ` +
      `<button type="button" class="btn btn-sm btn-primary" data-action="sync-save-client" data-node-id="${String(nodeId).replace(/"/g, "&quot;")}"><i class="fas fa-save"></i> Сохранить</button> ` +
      '<button type="button" class="btn btn-sm btn-secondary" data-action="sync-cancel-edit">Отмена</button>' +
      "</div>";

    const sel = document.getElementById(`syncEditSelect_${nodeId}`);
    if (sel && currentName) sel.value = currentName;
  }

  function saveSyncClientDisplayName(nodeId) {
    const sel = document.getElementById(`syncEditSelect_${nodeId}`);
    const displayName = sel ? (sel.value || "").trim() : "";
    fetch(`/api/sync/clients/${encodeURIComponent(nodeId)}/display_name`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ display_name: displayName || null }),
    })
      .then((r) => r.json())
      .then((data) => {
        if (data.error) {
          notyf.error(data.error);
          return;
        }
        notyf.success(displayName ? "Имя сохранено" : "Имя сброшено");
        loadSyncClientsSettings();
      })
      .catch(() => notyf.error("Не удалось сохранить настройки клиента"));
  }

  async function deleteSyncClientSettings(btn) {
    const item = btn && btn.closest ? btn.closest(".settings-sync-client-item") : null;
    const nodeId = item ? item.dataset.nodeId : null;
    if (!nodeId) return;
    const ok = globalThis.WespKioskDialog
      ? await globalThis.WespKioskDialog.confirm("Удалить этого клиента из синхронизации?")
      : globalThis.confirm("Удалить этого клиента из синхронизации?");
    if (!ok) return;

    fetch(`/api/sync/clients/${encodeURIComponent(nodeId)}`, { method: "DELETE" })
      .then((r) => r.json())
      .then((data) => {
        if (data.error) {
          notyf.error(data.error);
          return;
        }
        notyf.success(data.message || "Клиент удалён");
        loadSyncClientsSettings();
      })
      .catch(() => notyf.error("Не удалось сохранить настройки клиента"));
  }

  function toggleCredentialsForm() {
    const credForm = document.getElementById("credentialsForm");
    const userCard = document.querySelector(".settings-user-card--clickable");
    if (!credForm) return;

    const isOpen = credForm.style.display !== "none";
    credForm.style.display = isOpen ? "none" : "block";
    if (userCard) userCard.classList.toggle("open", !isOpen);
  }

  function toggleSyncForm() {
    const syncForm = document.getElementById("syncSettingsForm");
    const syncCard = document.querySelector(".settings-sync-card--clickable");
    if (!syncForm) return;

    const isOpen = syncForm.style.display !== "none";
    syncForm.style.display = isOpen ? "none" : "block";
    if (syncCard) syncCard.classList.toggle("open", !isOpen);
    if (!isOpen) loadSyncClientsSettings();
  }

  async function changeCredentials() {
    const oldLogin = (document.getElementById("oldLogin")?.value || "").trim();
    const oldPassword = document.getElementById("oldPassword")?.value || "";
    const newLogin = (document.getElementById("newLogin")?.value || "").trim();
    const newPassword = document.getElementById("newPassword")?.value || "";
    const confirmPassword = document.getElementById("confirmPassword")?.value || "";

    const wantsCredChange = !!(newLogin || newPassword || confirmPassword.trim());
    if (!wantsCredChange) {
      notyf.success("Настройки сохранены");
      closeSettings();
      return;
    }

    const validationError = validateCredentialChange({
      oldLogin,
      oldPassword,
      newLogin,
      newPassword,
      confirmPassword,
      passwordMinLen,
    });
    if (validationError) {
      notyf.error(validationError);
      return;
    }

    try {
      const response = await fetch("/api/auth/change_credentials", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          old_login: oldLogin,
          old_password: oldPassword,
          new_login: newLogin,
          new_password: newPassword,
          confirm_password: confirmPassword,
        }),
      });
      const data = await response.json();
      if (data.status === "success") {
        notyf.success(data.message);
        closeSettings();
        const userLogin = document.getElementById("userLogin");
        const mobileUserInfo = document.getElementById("mobileUserInfo");
        if (userLogin) userLogin.textContent = newLogin;
        if (mobileUserInfo) {
          mobileUserInfo.innerHTML = `<i class="fas fa-user"></i> ${newLogin}`;
        }
      } else {
        notyf.error(data.message);
      }
    } catch (error) {
      console.error("Ошибка при изменении учетных данных:", error);
      notyf.error("Ошибка при изменении учетных данных");
    }
  }

  applyTheme(getTheme());

  return {
    checkAuth,
    logout,
    setupMobileMenu,
    openSettings,
    closeSettings,
    toggleSyncForm,
    loadSyncClientsSettings,
    editSyncClientSettings,
    saveSyncClientDisplayName,
    deleteSyncClientSettings,
    toggleCredentialsForm,
    changeCredentials,
    initThemePicker,
    initHighContrastToggle,
    initThemeToggle,
  };
}
