Source: contexts/UserContext.jsx

import React, { createContext, useContext, useState, useEffect } from "react";
import apiService from "../services/api";

/**
 * @typedef {Object} User
 * @property {string} firstName - First name of the user
 * @property {string} lastName - Last name of the user
 * @property {string} email - Email address of the user
 * @property {number} age - Age of the user
 * @property {string} postalCode - Postal code of the user
 * @property {string} city - City of the user
 * @property {string} timestamp - ISO date string of registration
 */

/**
 * @typedef {Object} UserContextValue
 * @property {User[]} users - Array of registered users
 * @property {function(User): Promise<void>} addUser - Function to add a new user (async)
 * @property {function(): Promise<void>} refreshUsers - Function to refresh users from API (async)
 * @property {boolean} loading - Loading state for API operations
 * @property {string|null} error - Error message if API call fails
 */

const UserContext = createContext(undefined);

/**
 * UserProvider component that manages user state globally
 *
 * @component
 * @param {Object} props - Component props
 * @param {React.ReactNode} props.children - Child components
 * @returns {JSX.Element} Provider component
 */
export function UserProvider({ children }) {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  /**
   * Load users from API
   */
  const loadUsers = async () => {
    try {
      setLoading(true);
      setError(null);
      const fetchedUsers = await apiService.getUsers();
      setUsers(fetchedUsers);
    } catch (error) {
      console.error("Error loading users from API:", error);
      setError(error.message || "Failed to load users");
      setUsers([]);
    } finally {
      setLoading(false);
    }
  };

  /**
   * Add a new user via API
   *
   * @param {User} user - User object to add
   * @returns {Promise<Object>} Created user object
   * @throws {Error} If API call fails
   */
  const addUser = async (user) => {
    try {
      setLoading(true);
      setError(null);
      const createdUser = await apiService.createUser(user);
      setUsers((prevUsers) => [...prevUsers, createdUser]);
      return createdUser;
    } catch (error) {
      console.error("Error creating user:", error);
      setError(error.message || "Failed to create user");
      throw error;
    } finally {
      setLoading(false);
    }
  };

  /**
   * Refresh users from API
   */
  const refreshUsers = async () => {
    await loadUsers();
  };

  useEffect(() => {
    loadUsers();
  }, []);

  const value = {
    users,
    addUser,
    refreshUsers,
    loading,
    error,
  };

  return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
}

/**
 * Custom hook to use the UserContext
 *
 * @returns {UserContextValue} User context value
 * @throws {Error} If used outside of UserProvider
 */
export function useUsers() {
  const context = useContext(UserContext);
  if (context === undefined) {
    throw new Error("useUsers must be used within a UserProvider");
  }
  return context;
}

export default UserContext;