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

import ApiClient from "./ApiClient";

/**
 * HealthService - Handles Health Check API requests
 *
 * Backend API: GET /health
 * Documentation: cloud/maplepress-backend/docs/API.md (lines 38-60)
 *
 * Backend Handler: cloud/maplepress-backend/internal/interface/http/handler/healthcheck/healthcheck_handler.go
 *
 * Purpose: Check if the MaplePress backend service is running and healthy.
 * This is a simple endpoint that requires no authentication and can be used for:
 * - Monitoring service availability
 * - Load balancer health checks
 * - Application startup verification
 * - API connectivity testing
 */

/**
 * Check if the backend service is healthy
 *
 * @returns {Promise<Object>} Health status response
 * @throws {Error} If the service is unreachable or unhealthy
 *
 * Response format:
 * {
 *   status: string  // "healthy" if service is running
 * }
 *
 * Usage Example:
 * ```javascript
 * try {
 *   const health = await HealthService.checkHealth();
 *   if (health.status === 'healthy') {
 *     console.log('Backend is healthy');
 *   }
 * } catch (error) {
 *   console.error('Backend is down:', error.message);
 * }
 * ```
 */
async function checkHealth() {
  try {
    // Make unauthenticated GET request to health endpoint
    const response = await ApiClient.get("/health");

    // Return status
    return {
      status: response.status,
    };
  } catch (error) {
    // Map errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    // Network or connection errors
    if (
      message.includes("network") ||
      message.includes("fetch") ||
      message.includes("failed to fetch")
    ) {
      throw new Error(
        "Unable to connect to backend service. Please check your network connection."
      );
    }

    // Service unavailable
    if (message.includes("503") || message.includes("unavailable")) {
      throw new Error("Backend service is temporarily unavailable.");
    }

    // Generic error
    throw new Error(
      error.message || "Failed to check backend health status."
    );
  }
}

/**
 * Check if the backend is healthy (simple boolean check)
 *
 * @returns {Promise<boolean>} True if healthy, false otherwise
 *
 * Usage Example:
 * ```javascript
 * const isHealthy = await HealthService.isHealthy();
 * if (isHealthy) {
 *   console.log('Backend is ready');
 * }
 * ```
 */
async function isHealthy() {
  try {
    const health = await checkHealth();
    return health.status === "healthy";
  } catch (error) {
    // If we can't reach the service, it's not healthy
    console.error("Health check failed:", error);
    return false;
  }
}

/**
 * Wait for the backend to become healthy (useful for startup)
 *
 * @param {Object} options - Wait options
 * @param {number} options.maxAttempts - Maximum number of attempts (default: 30)
 * @param {number} options.retryDelayMs - Delay between attempts in ms (default: 1000)
 * @returns {Promise<boolean>} True if backend became healthy, false if timeout
 *
 * Usage Example:
 * ```javascript
 * const ready = await HealthService.waitUntilHealthy({ maxAttempts: 10 });
 * if (ready) {
 *   console.log('Backend is ready!');
 * } else {
 *   console.error('Backend did not become ready in time');
 * }
 * ```
 */
async function waitUntilHealthy(options = {}) {
  const { maxAttempts = 30, retryDelayMs = 1000 } = options;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      const healthy = await isHealthy();
      if (healthy) {
        console.log(`[HealthService] Backend is healthy (attempt ${attempt})`);
        return true;
      }
    } catch (error) {
      console.log(
        `[HealthService] Health check attempt ${attempt}/${maxAttempts} failed:`,
        error.message
      );
    }

    // Wait before next attempt (except on last attempt)
    if (attempt < maxAttempts) {
      await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
    }
  }

  console.error(
    `[HealthService] Backend did not become healthy after ${maxAttempts} attempts`
  );
  return false;
}

/**
 * Get detailed backend status with timing information
 *
 * @returns {Promise<Object>} Detailed health status
 *
 * Response format:
 * {
 *   healthy: boolean,        // Whether backend is healthy
 *   status: string,          // Status message
 *   responseTimeMs: number,  // Response time in milliseconds
 *   timestamp: Date          // When check was performed
 * }
 *
 * Usage Example:
 * ```javascript
 * const status = await HealthService.getDetailedStatus();
 * console.log(`Backend responded in ${status.responseTimeMs}ms`);
 * ```
 */
async function getDetailedStatus() {
  const startTime = Date.now();
  const timestamp = new Date();

  try {
    const health = await checkHealth();
    const responseTimeMs = Date.now() - startTime;

    return {
      healthy: health.status === "healthy",
      status: health.status,
      responseTimeMs,
      timestamp,
    };
  } catch (error) {
    const responseTimeMs = Date.now() - startTime;

    return {
      healthy: false,
      status: "unhealthy",
      error: error.message,
      responseTimeMs,
      timestamp,
    };
  }
}

// Export service
const HealthService = {
  checkHealth,
  isHealthy,
  waitUntilHealthy,
  getDetailedStatus,
};

export default HealthService;
