// File: src/services/API/UserService.js

import ApiClient from "./ApiClient";

/**
 * UserService - Handles User Management API requests
 *
 * Backend API:
 * - POST /api/v1/users (Create User)
 * - GET /api/v1/users/{id} (Get User by ID)
 *
 * Documentation: cloud/maplepress-backend/docs/API.md (lines 560-660)
 *
 * Purpose: Manage users within a tenant (organization).
 * All user operations require tenant context via X-Tenant-ID header.
 *
 * IMPORTANT: These endpoints require tenant context (X-Tenant-ID header).
 * The ApiClient should be enhanced to automatically add this header based on
 * the current user's tenant from AuthManager.
 */

/**
 * Create a new user within a tenant
 *
 * @param {Object} userData - User creation data
 * @param {string} userData.email - User's email address
 * @param {string} userData.name - User's full name
 * @param {string} tenantId - Tenant ID for context (optional if using current tenant)
 * @returns {Promise<Object>} Created user data
 * @throws {Error} If creation fails or validation errors occur
 *
 * Response format (transformed to camelCase):
 * {
 *   id: string,          // User ID (UUID)
 *   email: string,       // User email
 *   name: string,        // User name
 *   createdAt: Date      // Creation timestamp
 * }
 */
async function createUser(userData, tenantId = null) {
  // Validate required fields
  if (!userData || typeof userData !== "object") {
    throw new Error("User data is required");
  }

  if (!userData.email || typeof userData.email !== "string") {
    throw new Error("User email is required");
  }

  if (!userData.name || typeof userData.name !== "string") {
    throw new Error("User name is required");
  }

  // Validate email format
  const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailPattern.test(userData.email)) {
    throw new Error("Invalid email format");
  }

  // Prepare request body (snake_case for backend)
  const requestBody = {
    email: userData.email.trim().toLowerCase(),
    name: userData.name.trim(),
  };

  try {
    // Prepare options with tenant context if provided
    const options = {};
    if (tenantId) {
      options.headers = {
        "X-Tenant-ID": tenantId,
      };
    }

    // Make authenticated API request with tenant context
    const response = await ApiClient.post("/api/v1/users", requestBody, options);

    // Transform response to camelCase for frontend
    return {
      id: response.id,
      email: response.email,
      name: response.name,
      createdAt: new Date(response.created_at),
    };
  } catch (error) {
    // Map backend errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Authentication required. Please log in to continue."
      );
    }

    if (message.includes("conflict") || message.includes("409") || message.includes("already exists")) {
      throw new Error(
        "User email already exists in this tenant."
      );
    }

    if (message.includes("tenant") && message.includes("400")) {
      throw new Error(
        "Tenant context required. Please provide X-Tenant-ID header."
      );
    }

    if (message.includes("email")) {
      throw new Error("Invalid email address provided.");
    }

    if (message.includes("name")) {
      throw new Error("Invalid name provided.");
    }

    // Generic error
    throw new Error(
      error.message || "Failed to create user. Please try again."
    );
  }
}

/**
 * Get user by ID within a tenant context
 *
 * @param {string} userId - User ID (UUID)
 * @param {string} tenantId - Tenant ID for context (optional if using current tenant)
 * @returns {Promise<Object>} User data
 * @throws {Error} If retrieval fails or user not found
 *
 * Response format (transformed to camelCase):
 * {
 *   id: string,          // User ID (UUID)
 *   email: string,       // User email
 *   name: string,        // User name
 *   createdAt: Date,     // Creation timestamp
 *   updatedAt: Date      // Last update timestamp
 * }
 */
async function getUserById(userId, tenantId = null) {
  // Validate input
  if (!userId || typeof userId !== "string") {
    throw new Error("User ID is required");
  }

  // Basic UUID validation
  const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
  if (!uuidPattern.test(userId)) {
    throw new Error("Invalid user ID format");
  }

  try {
    // Prepare options with tenant context if provided
    const options = {};
    if (tenantId) {
      options.headers = {
        "X-Tenant-ID": tenantId,
      };
    }

    // Make authenticated GET request with tenant context
    const response = await ApiClient.get(`/api/v1/users/${userId}`, options);

    // Transform response to camelCase for frontend
    return {
      id: response.id,
      email: response.email,
      name: response.name,
      createdAt: new Date(response.created_at),
      updatedAt: new Date(response.updated_at),
    };
  } catch (error) {
    // Map backend errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Authentication required. Please log in to continue."
      );
    }

    if (message.includes("not found") || message.includes("404")) {
      throw new Error("User not found in this tenant.");
    }

    if (message.includes("tenant") && message.includes("400")) {
      throw new Error(
        "Tenant context required. Please provide X-Tenant-ID header."
      );
    }

    // Generic error
    throw new Error(
      error.message || "Failed to retrieve user. Please try again."
    );
  }
}

/**
 * Validate email format
 *
 * @param {string} email - Email to validate
 * @returns {Object} { valid: boolean, error: string|null }
 */
function validateEmail(email) {
  if (!email || typeof email !== "string") {
    return { valid: false, error: "Email is required" };
  }

  const trimmedEmail = email.trim();

  if (trimmedEmail.length === 0) {
    return { valid: false, error: "Email cannot be empty" };
  }

  // Check email format
  const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailPattern.test(trimmedEmail)) {
    return { valid: false, error: "Invalid email format" };
  }

  if (trimmedEmail.length > 255) {
    return { valid: false, error: "Email must be 255 characters or less" };
  }

  return { valid: true, error: null };
}

/**
 * Validate user name
 *
 * @param {string} name - Name to validate
 * @returns {Object} { valid: boolean, error: string|null }
 */
function validateName(name) {
  if (!name || typeof name !== "string") {
    return { valid: false, error: "Name is required" };
  }

  const trimmedName = name.trim();

  if (trimmedName.length === 0) {
    return { valid: false, error: "Name cannot be empty" };
  }

  if (trimmedName.length < 2) {
    return { valid: false, error: "Name must be at least 2 characters" };
  }

  if (trimmedName.length > 100) {
    return { valid: false, error: "Name must be 100 characters or less" };
  }

  return { valid: true, error: null };
}

/**
 * Validate UUID format
 *
 * @param {string} uuid - UUID to validate
 * @returns {boolean} True if valid UUID
 */
function isValidUUID(uuid) {
  if (!uuid || typeof uuid !== "string") {
    return false;
  }

  const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
  return uuidPattern.test(uuid);
}

// Export service
const UserService = {
  createUser,
  getUserById,
  validateEmail,
  validateName,
  isValidUUID,
};

export default UserService;
