/**
 * Hook for validating the session on app mount.
 *
 * Calls the backend to confirm the session is still valid, rather than relying
 * solely on cached sessionStorage. Handles network errors gracefully by not
 * logging out — only explicit 401/403 responses trigger logout.
 */

import { useCallback, useEffect, useState } from "react";
import * as authApi from "../api/auth";
import { ApiError, isAuthError } from "../api/client";

export interface UseSessionValidationResult {
  /** `true` when the validation check is in flight. */
  isLoading: boolean;
  /** An error if validation failed for a reason other than 401/403. */
  error: Error | null;
}

/**
 * Validate the session on mount.
 *
 * This hook is called once during app initialization to confirm the session
 * is valid on the backend. It handles three cases:
 *
 * 1. **Valid session (200)** — `onSessionValid()` is called.
 * 2. **Invalid session (401/403)** — `onSessionExpired()` is called to log out.
 * 3. **Network error** — `onNetworkError()` is called. The user is not logged out
 *    because the backend may be temporarily unreachable.
 *
 * @param onSessionValid - Callback when session is confirmed valid.
 * @param onSessionExpired - Callback when session is invalid (401/403).
 * @param onNetworkError - Callback when a network error occurs.
 * @returns An object with `isLoading` and `error` states.
 */
export function useSessionValidation(
  onSessionValid: () => void,
  onSessionExpired: () => void,
  onNetworkError?: (error: Error) => void,
): UseSessionValidationResult {
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [error, setError] = useState<Error | null>(null);

  const validate = useCallback(async (): Promise<void> => {
    setIsLoading(true);
    setError(null);

    try {
      await authApi.validateSession();
      onSessionValid();
    } catch (err) {
      if (err instanceof ApiError && isAuthError(err)) {
        // Explicit 401/403 — session is invalid or expired.
        onSessionExpired();
      } else if (err instanceof Error) {
        // Network error or other issue — don't log out.
        setError(err);
        onNetworkError?.(err);
      } else {
        const unknownError = new Error("Unknown error during session validation");
        setError(unknownError);
        onNetworkError?.(unknownError);
      }
    } finally {
      setIsLoading(false);
    }
  }, [onSessionValid, onSessionExpired, onNetworkError]);

  useEffect(() => {
    void validate();
  }, [validate]);

  return { isLoading, error };
}
