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

import ApiClient from "./ApiClient";

/**
 * AdminService - Handles Admin API requests
 *
 * Backend API:
 * - GET /api/v1/admin/account-status (Check Account Lock Status)
 * - POST /api/v1/admin/unlock-account (Unlock Locked Account)
 *
 * Source Files:
 * - cloud/maplepress-backend/internal/interface/http/handler/admin/account_status_handler.go
 * - cloud/maplepress-backend/internal/interface/http/handler/admin/unlock_account_handler.go
 *
 * Purpose: Admin operations for account management, specifically handling
 * account lockouts due to failed login attempts (CWE-307 protection).
 *
 * IMPORTANT: These endpoints require admin authentication.
 * Only users with admin/root roles should have access to these operations.
 */

/**
 * Check if a user account is locked due to failed login attempts
 *
 * @param {string} email - User's email address to check
 * @returns {Promise<Object>} Account lock status and details
 * @throws {Error} If check fails or validation errors occur
 *
 * Response format (transformed to camelCase):
 * {
 *   email: string,              // User's email
 *   isLocked: boolean,          // Whether account is locked
 *   failedAttempts: number,     // Number of failed login attempts
 *   remainingTime: string,      // Human-readable time until unlock (e.g., "5 minutes 30 seconds")
 *   remainingSeconds: number    // Seconds until automatic unlock
 * }
 */
async function getAccountStatus(email) {
  // Validate email
  if (!email || typeof email !== "string") {
    throw new Error("Email is required");
  }

  const trimmedEmail = email.trim();
  if (trimmedEmail.length === 0) {
    throw new Error("Email cannot be empty");
  }

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

  try {
    // Make authenticated GET request with email as query parameter
    const response = await ApiClient.get("/api/v1/admin/account-status", {
      params: { email: trimmedEmail },
    });

    // Transform response to camelCase for frontend
    return {
      email: response.email,
      isLocked: response.is_locked,
      failedAttempts: response.failed_attempts,
      remainingTime: response.remaining_time || null,
      remainingSeconds: response.remaining_seconds || 0,
    };
  } catch (error) {
    // Map backend errors to user-friendly messages
    const message = error.message?.toLowerCase() || "";

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Admin authentication required. Please log in with admin credentials."
      );
    }

    if (message.includes("forbidden") || message.includes("403")) {
      throw new Error(
        "Access denied. Admin privileges required for this operation."
      );
    }

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

    // Generic error
    throw new Error(
      error.message || "Failed to check account status. Please try again."
    );
  }
}

/**
 * Unlock a user account that has been locked due to failed login attempts
 *
 * @param {string} email - User's email address to unlock
 * @returns {Promise<Object>} Unlock operation result
 * @throws {Error} If unlock fails or validation errors occur
 *
 * Response format (transformed to camelCase):
 * {
 *   success: boolean,
 *   message: string,
 *   email: string
 * }
 *
 * Security Event: This operation logs a security event (ACCOUNT_UNLOCKED)
 * with the admin user ID who performed the unlock operation.
 */
async function unlockAccount(email) {
  // Validate email
  if (!email || typeof email !== "string") {
    throw new Error("Email is required");
  }

  const trimmedEmail = email.trim();
  if (trimmedEmail.length === 0) {
    throw new Error("Email cannot be empty");
  }

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

  // Prepare request body
  const requestBody = {
    email: trimmedEmail,
  };

  try {
    // Make authenticated POST request
    const response = await ApiClient.post(
      "/api/v1/admin/unlock-account",
      requestBody
    );

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

    if (message.includes("unauthorized") || message.includes("401")) {
      throw new Error(
        "Admin authentication required. Please log in with admin credentials."
      );
    }

    if (message.includes("forbidden") || message.includes("403")) {
      throw new Error(
        "Access denied. Admin privileges required for this operation."
      );
    }

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

    if (message.includes("not locked")) {
      throw new Error("Account is not currently locked.");
    }

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

/**
 * Check if an account needs unlocking (is locked with remaining time)
 *
 * @param {string} email - User's email address to check
 * @returns {Promise<boolean>} True if account is locked and needs admin unlock
 * @throws {Error} If check fails
 */
async function needsUnlock(email) {
  try {
    const status = await getAccountStatus(email);
    return status.isLocked && status.remainingSeconds > 0;
  } catch (error) {
    // If we can't check status, assume no unlock needed
    console.error("Failed to check if account needs unlock:", error);
    return false;
  }
}

/**
 * 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 };
}

/**
 * Format remaining time for display
 *
 * @param {number} seconds - Seconds remaining
 * @returns {string} Formatted time string (e.g., "5 minutes 30 seconds")
 */
function formatRemainingTime(seconds) {
  if (seconds <= 0) {
    return "0 seconds";
  }

  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = seconds % 60;

  const parts = [];
  if (hours > 0) {
    parts.push(`${hours} ${hours === 1 ? "hour" : "hours"}`);
  }
  if (minutes > 0) {
    parts.push(`${minutes} ${minutes === 1 ? "minute" : "minutes"}`);
  }
  if (secs > 0 || parts.length === 0) {
    parts.push(`${secs} ${secs === 1 ? "second" : "seconds"}`);
  }

  return parts.join(" ");
}

// Export service
const AdminService = {
  getAccountStatus,
  unlockAccount,
  needsUnlock,
  validateEmail,
  formatRemainingTime,
};

export default AdminService;
