/**
 * Shared Auth Store Factory
 *
 * Creates a Pinia auth store that can be used by any ROA2WEB application.
 * Each app passes its own apiService instance configured with the correct baseURL.
 *
 * Usage:
 *   import { createAuthStore } from '@shared/frontend/stores/auth';
 *   import { apiService } from '../services/api';
 *   export const useAuthStore = createAuthStore(apiService);
 *
 * Multi-Server Login Flow (US-010):
 *   1. Call checkEmail(email) to verify email exists and get available servers
 *   2. If multiple servers, user selects one; if single server, auto-select
 *   3. Call login({username, password, server_id}) to authenticate
 *   4. Server ID is saved to localStorage for next login pre-selection
 */

import { defineStore } from "pinia";
import { ref, computed } from "vue";

// localStorage keys
const STORAGE_KEYS = {
  ACCESS_TOKEN: "access_token",
  REFRESH_TOKEN: "refresh_token",
  USER: "user",
  LAST_SERVER_ID: "last_server_id",
  AUTH_MODE: "auth_mode",
};

// sessionStorage keys (tab-scoped, auto-cleared on tab close)
const SESSION_KEYS = {
  PENDING_2FA: "pending_2fa",
};

/**
 * Returnează cheia localStorage pentru tokenul de trusted device.
 * Cheia e per-user și per-server pentru izolare corectă.
 * Exemplu: "trusted_device_MARIUS M_romfast"
 */
const _getTrustedDeviceKey = (username, serverId) => {
  const base = `trusted_device_${(username || "unknown").toUpperCase()}`;
  return serverId ? `${base}_${serverId}` : base;
};

/**
 * Caută orice token de trusted device, indiferent de username sau server.
 * Backend validează oricum username-ul corect.
 */
const _findAnyTrustedDeviceToken = () => {
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    if (key && key.startsWith("trusted_device_")) {
      const val = localStorage.getItem(key);
      if (val) return val;
    }
  }
  return null;
};

/**
 * Factory function to create an auth store with the provided API service
 * @param {Object} apiService - Axios instance configured for the app's API
 * @param {Object} options - Optional configuration
 * @param {Function} options.onLogout - Callback to reset other stores on logout (US-028)
 * @returns {Function} Pinia store definition
 */
export function createAuthStore(apiService, options = {}) {
  return defineStore("auth", () => {
    // State - Core auth
    const accessToken = ref(localStorage.getItem(STORAGE_KEYS.ACCESS_TOKEN));
    const refreshToken = ref(localStorage.getItem(STORAGE_KEYS.REFRESH_TOKEN));
    const user = ref(JSON.parse(localStorage.getItem(STORAGE_KEYS.USER) || "null"));
    const isLoading = ref(false);
    const error = ref(null);

    // State - Auth mode detection (US-011 - Backward Compatibility)
    // "single-server": legacy username/password login
    // "multi-server": email-based login with server selection
    const authMode = ref(localStorage.getItem(STORAGE_KEYS.AUTH_MODE) || null);
    const isLoadingAuthMode = ref(false);

    // State - Multi-step login (US-010)
    // Login steps: 'email' -> 'server' (if multiple) -> 'password' -> 'complete'
    // In single-server mode: 'username' -> 'password' -> 'complete'
    const loginStep = ref("loading"); // Start with loading until auth mode is determined
    const loginEmail = ref("");
    const loginUsername = ref(""); // For single-server mode (US-011)
    const availableServers = ref([]); // [{id: 'romfast', name: 'Romfast - Producție'}, ...]
    const selectedServerId = ref(localStorage.getItem(STORAGE_KEYS.LAST_SERVER_ID) || null);
    const isCheckingEmail = ref(false);

    // Flag pentru a preveni 401 interceptor în timpul autentificării
    // Când este true, interceptorul 401 din App.vue nu va face redirect la /login
    // Acest lucru permite modalului de server switch să gestioneze erorile de parolă
    const isAuthenticating = ref(false);

    // State - URL pre-selection (US-004)
    // Allows URL bookmark to pre-select a server (e.g., /login?server=romfast)
    const preselectedServerId = ref(null);

    // State - 2FA (pasul 2 din fluxul de login cu email)
    const otpEmail = ref("");          // Email complet — trimis la /auth/verify-2fa-code
    const otpMaskedEmail = ref("");    // Email mascat pentru display ("m***@romfast.ro")
    const is2FALoading = ref(false);   // Loading state pt butonul "Verifică"
    const resendCountdown = ref(0);    // Countdown 60s pt butonul "Retrimite codul"
    let _resendTimer = null;           // Interval timer intern (nu ref — nu e nevoie de reactivitate)

    // State - pending server ID pentru 2FA în contextul server switch
    // Login() returnează requires_2fa înainte de a actualiza selectedServerId,
    // deci verify2FA() trebuie să folosească pendingServerId pentru server-ul corect
    const pendingServerId = ref(null);

    // Getters
    const isAuthenticated = computed(() => !!accessToken.value);
    const currentUser = computed(() => user.value);

    // Getters - Auth mode (US-011)
    const isSingleServerMode = computed(() => authMode.value === "single-server");
    const isMultiServerMode = computed(() => authMode.value === "multi-server");

    // Getters - Multi-step login (US-010)
    const hasMultipleServers = computed(() => availableServers.value.length > 1);
    const lastServerId = computed(() => localStorage.getItem(STORAGE_KEYS.LAST_SERVER_ID));

    // Getter - Server name for display (US-026)
    const serverName = computed(() => {
      // If authenticated, get from JWT payload (user.server_name)
      if (user.value?.server_name) {
        return user.value.server_name;
      }
      // Fallback: search in availableServers
      const server = availableServers.value.find(s => s.id === selectedServerId.value);
      return server?.name || selectedServerId.value?.toUpperCase() || null;
    });

    // Actions

    /**
     * Get authentication mode from server (US-011 - Backward Compatibility)
     * Determines whether to use single-server (username/password) or
     * multi-server (email-based) login flow.
     *
     * @returns {Promise<{mode: string, supports_email_login: boolean}>}
     */
    const getAuthMode = async () => {
      isLoadingAuthMode.value = true;

      try {
        const response = await apiService.get("/system/auth-mode");
        const { mode, supports_email_login } = response.data;

        authMode.value = mode;
        localStorage.setItem(STORAGE_KEYS.AUTH_MODE, mode);

        // Try to restore pending 2FA session (mobile page reload)
        if (_restore2FASession()) {
          _startResendCountdown();
          return { mode, supports_email_login };
        }

        // Set initial login step based on auth mode
        if (mode === "single-server") {
          loginStep.value = "username";
        } else {
          loginStep.value = "email";
        }

        return { mode, supports_email_login };
      } catch (err) {
        console.error("Failed to get auth mode:", err);
        // Default to single-server mode on error (backward compatible)
        authMode.value = "single-server";
        loginStep.value = "username";
        return { mode: "single-server", supports_email_login: false };
      } finally {
        isLoadingAuthMode.value = false;
      }
    };

    /**
     * Check if identity (email or username) exists in the system and get available servers (US-010, US-013)
     * @param {string} identity - Email address or username to check
     * @returns {Promise<{exists: boolean, servers: Array<{id: string, name: string}>, identity_type: string}>}
     */
    const checkIdentity = async (identity) => {
      isCheckingEmail.value = true;
      error.value = null;

      try {
        // Use new check-identity endpoint (US-013)
        const response = await apiService.post("/auth/check-identity", { identity });
        const { exists, servers, identity_type } = response.data;

        loginEmail.value = identity; // Store identity (could be email or username)
        availableServers.value = servers;

        if (exists && servers.length > 0) {
          // Server selection priority (US-004):
          // 1. preselectedServerId (from URL ?server=xyz)
          // 2. lastServer (from localStorage)
          // 3. First server in list
          const lastServer = localStorage.getItem(STORAGE_KEYS.LAST_SERVER_ID);

          if (preselectedServerId.value && servers.some((s) => s.id === preselectedServerId.value)) {
            // URL pre-selection takes highest priority
            selectedServerId.value = preselectedServerId.value;
          } else if (lastServer && servers.some((s) => s.id === lastServer)) {
            // Fall back to last used server
            selectedServerId.value = lastServer;
          } else {
            // Default to first server
            selectedServerId.value = servers[0].id;
          }

          // Skip server selection step if only one server available
          if (servers.length === 1) {
            loginStep.value = "password";
          } else {
            loginStep.value = "server";
          }
        }

        return { exists, servers, identity_type };
      } catch (err) {
        const errorMessage = err.response?.data?.detail || "Eroare la verificare";
        error.value = errorMessage;
        return { exists: false, servers: [], identity_type: "unknown", error: errorMessage };
      } finally {
        isCheckingEmail.value = false;
      }
    };

    /**
     * Check if email exists in the system and get available servers (US-010)
     * DEPRECATED: Use checkIdentity for dual email/username support (US-013)
     * @param {string} email - Email address to check
     * @returns {Promise<{exists: boolean, servers: Array<{id: string, name: string}>}>}
     */
    const checkEmail = async (email) => {
      // Delegate to checkIdentity for backward compatibility
      const result = await checkIdentity(email);
      return { exists: result.exists, servers: result.servers };
    };

    /**
     * Login with credentials and optional server_id (US-010)
     * @param {Object} credentials - {username, password, server_id?}
     * @returns {Promise<{success: boolean, error?: string}>}
     */
    const login = async (credentials) => {
      isAuthenticating.value = true;  // Previne 401 interceptor redirect
      isLoading.value = true;
      error.value = null;

      try {
        // Build request payload
        const payload = {
          username: credentials.username,
          password: credentials.password,
        };

        // Add server_id if provided (multi-server mode)
        if (credentials.server_id) {
          payload.server_id = credentials.server_id;
        }

        // Trusted device: trimitem tokenul stocat local pentru posibil skip 2FA
        // Fallback cross-server: dacă nu există token pentru serverul curent, căutăm orice token al utilizatorului
        const tdKey = _getTrustedDeviceKey(credentials.username, credentials.server_id);
        const storedTrustedToken = localStorage.getItem(tdKey) || _findAnyTrustedDeviceToken();
        if (storedTrustedToken) {
          payload.trusted_device_token = storedTrustedToken;
        }

        const response = await apiService.post("/auth/login", payload);
        const responseData = response.data;

        // 2FA: backend cere verificare cod pe email
        if (responseData.requires_2fa === true) {
          otpEmail.value = responseData.email;
          otpMaskedEmail.value = responseData.masked_email;
          // Salvăm server_id pending — verify2FA() îl va folosi în loc de selectedServerId
          pendingServerId.value = credentials.server_id || null;
          loginStep.value = "2fa";
          _save2FASession();
          _startResendCountdown();
          return { success: true, requires_2fa: true, masked_email: responseData.masked_email };
        }

        // Flow normal — extragem tokens
        const { access_token, refresh_token, user: userData } = responseData;

        // IMPORTANT: Update selectedServerId BEFORE user.value to ensure
        // the companies store watch uses the correct server ID for localStorage key
        // (US-027: Multi-server company selection persistence)
        if (credentials.server_id) {
          selectedServerId.value = credentials.server_id;
          localStorage.setItem(STORAGE_KEYS.LAST_SERVER_ID, credentials.server_id);
        } else {
          // Single-server mode: clear any stale server_id from previous multi-server session
          selectedServerId.value = null;
        }

        accessToken.value = access_token;
        refreshToken.value = refresh_token;
        user.value = userData;

        localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, access_token);
        localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, refresh_token);
        localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(userData));

        apiService.defaults.headers.common["Authorization"] = `Bearer ${access_token}`;

        // Reset login step state
        loginStep.value = "complete";

        return { success: true };
      } catch (err) {
        error.value = err.response?.data?.detail || "Login failed";
        return { success: false, error: error.value };
      } finally {
        isLoading.value = false;
        isAuthenticating.value = false;  // Reset flag în finally pentru a garanta cleanup
      }
    };

    const logout = () => {
      // US-031 FIX: Save username and serverId BEFORE clearing them
      // This allows resetAllStores to properly clear localStorage keys
      const logoutContext = {
        username: user.value?.username,
        serverId: selectedServerId.value
      };

      accessToken.value = null;
      refreshToken.value = null;
      user.value = null;
      error.value = null;

      // Reset multi-step login state
      loginStep.value = "email";
      loginEmail.value = "";
      availableServers.value = [];
      // Note: Don't clear selectedServerId - keep it for next login pre-selection

      // Reset 2FA state
      otpEmail.value = "";
      otpMaskedEmail.value = "";
      is2FALoading.value = false;
      pendingServerId.value = null;
      _stopResendCountdown();
      _clear2FASession();

      localStorage.removeItem(STORAGE_KEYS.ACCESS_TOKEN);
      localStorage.removeItem(STORAGE_KEYS.REFRESH_TOKEN);
      localStorage.removeItem(STORAGE_KEYS.USER);
      // Note: Don't remove LAST_SERVER_ID - keep it for next login

      delete apiService.defaults.headers.common["Authorization"];

      // US-028/US-031: Call onLogout callback with context to reset other stores
      // Context includes username and serverId saved BEFORE clearing user state
      // This allows proper cleanup of localStorage keys
      if (options.onLogout) {
        try {
          options.onLogout(logoutContext);
        } catch (err) {
          console.error("[Auth] Error in onLogout callback:", err);
        }
      }
    };

    const refreshAccessToken = async () => {
      if (!refreshToken.value) {
        logout();
        return false;
      }

      try {
        const response = await apiService.post("/auth/refresh", {
          refresh_token: refreshToken.value,
        });

        const { access_token } = response.data;
        accessToken.value = access_token;
        localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, access_token);
        apiService.defaults.headers.common["Authorization"] = `Bearer ${access_token}`;

        return true;
      } catch (err) {
        console.error("Token refresh failed:", err);
        logout();
        return false;
      }
    };

    const initializeAuth = () => {
      if (accessToken.value) {
        apiService.defaults.headers.common["Authorization"] = `Bearer ${accessToken.value}`;
      }
    };

    const clearError = () => {
      error.value = null;
    };

    /**
     * Reset login flow to initial state (US-010, US-011)
     * Called when user wants to change email/username
     */
    const resetLoginFlow = () => {
      // Reset step based on auth mode
      if (authMode.value === "single-server") {
        loginStep.value = "username";
      } else {
        loginStep.value = "email";
      }
      loginEmail.value = "";
      loginUsername.value = "";
      availableServers.value = [];
      error.value = null;
      // Keep selectedServerId from localStorage for pre-selection

      // Reset 2FA state
      otpEmail.value = "";
      otpMaskedEmail.value = "";
      is2FALoading.value = false;
      pendingServerId.value = null;
      _stopResendCountdown();
      _clear2FASession();
    };

    /**
     * Go to password step (US-010)
     * Called after server selection
     */
    const goToPasswordStep = () => {
      loginStep.value = "password";
    };

    /**
     * Set selected server ID (US-010)
     * @param {string} serverId - Server ID to select
     */
    const setSelectedServer = (serverId) => {
      selectedServerId.value = serverId;
    };

    /**
     * Set pre-selected server ID from URL bookmark (US-004)
     * Called from LoginView when ?server=xyz query param is present.
     * The server will be validated against available servers in checkIdentity().
     * @param {string} serverId - Server ID to pre-select
     */
    const setPreselectedServer = (serverId) => {
      preselectedServerId.value = serverId;
    };

    // -------------------------------------------------------------------------
    // 2FA HELPERS — countdown timer
    // -------------------------------------------------------------------------

    const _startResendCountdown = () => {
      resendCountdown.value = 60;
      _stopResendCountdown(); // Curăță orice timer anterior
      _resendTimer = setInterval(() => {
        if (resendCountdown.value > 0) {
          resendCountdown.value--;
        } else {
          _stopResendCountdown();
        }
      }, 1000);
    };

    const _stopResendCountdown = () => {
      if (_resendTimer) {
        clearInterval(_resendTimer);
        _resendTimer = null;
      }
      resendCountdown.value = 0;
    };

    // -------------------------------------------------------------------------
    // 2FA SESSION PERSISTENCE (mobile page reload fix)
    // -------------------------------------------------------------------------

    const _save2FASession = () => {
      try {
        sessionStorage.setItem(SESSION_KEYS.PENDING_2FA, JSON.stringify({
          otpEmail: otpEmail.value,
          otpMaskedEmail: otpMaskedEmail.value,
          pendingServerId: pendingServerId.value,
          loginEmail: loginEmail.value,
          selectedServerId: selectedServerId.value,
          savedAt: Date.now(),
        }));
      } catch (e) {
        // sessionStorage may be unavailable (Safari private mode)
      }
    };

    const _clear2FASession = () => {
      try { sessionStorage.removeItem(SESSION_KEYS.PENDING_2FA); } catch (e) { /* ignore */ }
    };

    const _restore2FASession = () => {
      try {
        const raw = sessionStorage.getItem(SESSION_KEYS.PENDING_2FA);
        if (!raw) return false;

        const session = JSON.parse(raw);

        // Expire after 5 minutes (matches OTP_EXPIRY_MINUTES)
        if (Date.now() - session.savedAt > 5 * 60 * 1000) {
          _clear2FASession();
          return false;
        }

        if (!session.otpEmail || !session.otpMaskedEmail) {
          _clear2FASession();
          return false;
        }

        // Restore state
        otpEmail.value = session.otpEmail;
        otpMaskedEmail.value = session.otpMaskedEmail;
        pendingServerId.value = session.pendingServerId || null;
        loginEmail.value = session.loginEmail || "";
        selectedServerId.value = session.selectedServerId || selectedServerId.value;
        loginStep.value = "2fa";

        return true;
      } catch (e) {
        _clear2FASession();
        return false;
      }
    };

    // -------------------------------------------------------------------------
    // 2FA ACTIONS
    // -------------------------------------------------------------------------

    /**
     * Verifică codul OTP introdus de utilizator (pasul 2 al 2FA).
     * Dacă codul este valid, stochează JWT tokens și completează autentificarea.
     *
     * @param {Object} params - {code: "483921", trustDevice?: false}
     * @returns {Promise<{success: boolean, error?: string}>}
     */
    const verify2FA = async ({ code, trustDevice = false }) => {
      is2FALoading.value = true;
      error.value = null;

      try {
        const payload = {
          code: code.trim(),
          email: otpEmail.value,
          trust_device: trustDevice,
        };

        // Adăugăm server_id — folosim pendingServerId dacă există (server switch context)
        const effectiveServerId = pendingServerId.value || selectedServerId.value;
        if (effectiveServerId) {
          payload.server_id = effectiveServerId;
        }

        const response = await apiService.post("/auth/verify-2fa-code", payload);
        const { access_token, refresh_token, user: userData, trusted_device_token } = response.data;

        // IMPORTANT: Commit pendingServerId -> selectedServerId BEFORE user (pattern existent)
        if (effectiveServerId) {
          selectedServerId.value = effectiveServerId;
          localStorage.setItem(STORAGE_KEYS.LAST_SERVER_ID, effectiveServerId);
        }

        accessToken.value = access_token;
        refreshToken.value = refresh_token;
        user.value = userData;

        localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, access_token);
        localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, refresh_token);
        localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(userData));

        apiService.defaults.headers.common["Authorization"] = `Bearer ${access_token}`;

        // Salvează tokenul de trusted device dacă utilizatorul a bifat "Ține minte"
        if (trusted_device_token && userData?.username) {
          const tdKey = _getTrustedDeviceKey(userData.username, effectiveServerId);
          localStorage.setItem(tdKey, trusted_device_token);
        }

        // Curăță starea 2FA
        otpEmail.value = "";
        otpMaskedEmail.value = "";
        pendingServerId.value = null;
        _stopResendCountdown();
        loginStep.value = "complete";
        _clear2FASession();

        const backupCodes = response.data.backup_codes;
        return { success: true, backup_codes: backupCodes };
      } catch (err) {
        error.value = err.response?.data?.detail || "Verificare eșuată. Încercați din nou.";
        return { success: false, error: error.value };
      } finally {
        is2FALoading.value = false;
      }
    };

    /**
     * Retrimite codul OTP pe email (butonul "Retrimite codul").
     * Resetează countdown-ul de 60 secunde.
     *
     * @returns {Promise<{success: boolean, error?: string}>}
     */
    const resendOTP = async () => {
      // Nu permite retrimis dacă countdown-ul nu a ajuns la 0
      if (resendCountdown.value > 0) {
        return { success: false, error: `Așteptați ${resendCountdown.value} secunde` };
      }

      error.value = null;

      try {
        const payload = { email: otpEmail.value };
        const effectiveServerId = pendingServerId.value || selectedServerId.value;
        if (effectiveServerId) {
          payload.server_id = effectiveServerId;
        }

        await apiService.post("/auth/resend-2fa-code", payload);

        // Resetăm countdown-ul
        _startResendCountdown();
        return { success: true };
      } catch (err) {
        error.value = err.response?.data?.detail || "Nu s-a putut retrimite codul.";
        return { success: false, error: error.value };
      }
    };

    /**
     * Verifică un cod de backup (fallback când emailul nu sosește).
     * @param {Object} params - {code: "AB3K9PQR", serverId?: "romfast"}
     * @returns {Promise<{success: boolean, error?: string}>}
     */
    const verifyBackupCode = async ({ code, serverId, trustDevice = false }) => {
      is2FALoading.value = true;
      error.value = null;

      try {
        const payload = {
          code: code.trim().toUpperCase(),
          email: otpEmail.value,
          trust_device: trustDevice,
        };
        const effectiveServerId = serverId || pendingServerId.value || selectedServerId.value;
        if (effectiveServerId) payload.server_id = effectiveServerId;

        const response = await apiService.post("/auth/verify-backup-code", payload);
        const { access_token, refresh_token, user: userData, trusted_device_token } = response.data;

        if (effectiveServerId) {
          selectedServerId.value = effectiveServerId;
          localStorage.setItem(STORAGE_KEYS.LAST_SERVER_ID, effectiveServerId);
        }

        accessToken.value = access_token;
        refreshToken.value = refresh_token;
        user.value = userData;

        localStorage.setItem(STORAGE_KEYS.ACCESS_TOKEN, access_token);
        localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, refresh_token);
        localStorage.setItem(STORAGE_KEYS.USER, JSON.stringify(userData));

        apiService.defaults.headers.common["Authorization"] = `Bearer ${access_token}`;

        if (trusted_device_token && userData?.username) {
          const tdKey = _getTrustedDeviceKey(userData.username, effectiveServerId);
          localStorage.setItem(tdKey, trusted_device_token);
        }

        otpEmail.value = "";
        otpMaskedEmail.value = "";
        pendingServerId.value = null;
        _stopResendCountdown();
        loginStep.value = "complete";
        _clear2FASession();

        return { success: true };
      } catch (err) {
        error.value = err.response?.data?.detail || "Cod de recuperare invalid.";
        return { success: false, error: error.value };
      } finally {
        is2FALoading.value = false;
      }
    };

    /**
     * Switch to a different server without full logout (US-007)
     * Re-authenticates the current user on the new server.
     *
     * @param {string} newServerId - Server ID to switch to
     * @param {string} password - User's password for re-authentication
     * @returns {Promise<{success: boolean, error?: string}>}
     */
    const switchServer = async (newServerId, password) => {
      // Save current username BEFORE login() potentially modifies user state
      const currentUsername = user.value?.username;

      if (!currentUsername) {
        return { success: false, error: "Nu există utilizator autentificat" };
      }

      if (!newServerId) {
        return { success: false, error: "Server ID lipsește" };
      }

      // Re-authenticate on the new server using existing login() method
      const result = await login({
        username: currentUsername,
        password: password,
        server_id: newServerId
      });

      return result;
    };

    // Initialize on store creation
    initializeAuth();

    return {
      // State - Core auth
      accessToken,
      refreshToken,
      user,
      isLoading,
      error,

      // State - Auth mode (US-011)
      authMode,
      isLoadingAuthMode,

      // State - Multi-step login (US-010)
      loginStep,
      loginEmail,
      loginUsername,
      availableServers,
      selectedServerId,
      isCheckingEmail,
      isAuthenticating,  // Flag pentru a preveni 401 redirect în timpul login/server-switch
      preselectedServerId, // US-004: URL bookmark pre-selection

      // State - 2FA
      otpEmail,
      otpMaskedEmail,
      is2FALoading,
      resendCountdown,
      pendingServerId,

      // Getters
      isAuthenticated,
      currentUser,
      isSingleServerMode,
      isMultiServerMode,
      hasMultipleServers,
      lastServerId,
      serverName,

      // Actions - Core auth
      login,
      logout,
      refreshAccessToken,
      initializeAuth,
      clearError,

      // Actions - Auth mode (US-011)
      getAuthMode,

      // Actions - Multi-step login (US-010, US-013)
      checkIdentity,
      checkEmail, // Deprecated, delegates to checkIdentity
      resetLoginFlow,
      goToPasswordStep,
      setSelectedServer,
      setPreselectedServer, // US-004: URL bookmark pre-selection

      // Actions - Server switch (US-007)
      switchServer,

      // Actions - 2FA
      verify2FA,
      resendOTP,
      verifyBackupCode,
    };
  });
}
