// File: monorepo/web/maplefile-frontend/src/services/API/InviteEmail/InviteEmailAPIService.js
// Invite Email API Service - Handles sending invitation emails to non-registered users
import { parseRFC9457Error, createErrorFromProblem } from "../../../utils/rfc9457Parser.js";
import LocalStorageService from "../../Storage/LocalStorageService.js";

class InviteEmailAPIService {
  constructor() {
    this._apiClient = null;
    console.log(
      "[InviteEmailAPIService] API service initialized for sending invite emails",
    );
  }

  // Import ApiClient for requests
  async getApiClient() {
    if (!this._apiClient) {
      const { default: ApiClient } = await import("../ApiClient.js");
      this._apiClient = ApiClient;
    }
    return this._apiClient;
  }

  // Get authorization header for authenticated requests
  getAuthorizationHeader() {
    const accessToken = LocalStorageService.getAccessToken();
    if (accessToken) {
      return `JWT ${accessToken}`;
    }
    return null;
  }

  // Validate email format
  validateEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }

  // Sanitize email (lowercase and trim)
  sanitizeEmail(email) {
    return email.toLowerCase().trim();
  }

  /**
   * Send an invitation email to a non-registered user
   * @param {string} email - The email address to send the invitation to
   * @returns {Promise<{success: boolean, remaining_invites_today: number, message: string}>}
   */
  async sendInviteEmail(email) {
    try {
      console.log("[InviteEmailAPIService] Sending invite email to:", email);

      if (!email) {
        throw new Error("Email address is required");
      }

      // Sanitize email
      const sanitizedEmail = this.sanitizeEmail(email);

      // Validate email format
      if (!this.validateEmail(sanitizedEmail)) {
        throw new Error("Invalid email format");
      }

      // Get API base URL from environment
      const apiBaseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';

      // Get authorization header (required - endpoint needs authentication)
      const authHeader = this.getAuthorizationHeader();
      if (!authHeader) {
        throw new Error("Authentication required. Please log in to send invitations.");
      }

      // Make authenticated POST request
      const response = await fetch(
        `${apiBaseUrl}/api/v1/invites/send-email`,
        {
          method: 'POST',
          headers: {
            'Authorization': authHeader,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ email: sanitizedEmail }),
        }
      );

      if (!response.ok) {
        try {
          const errorData = await response.json();

          // Parse RFC 9457 error response
          const parsedError = parseRFC9457Error(errorData);
          if (parsedError) {
            throw createErrorFromProblem(parsedError);
          }

          // Fallback to legacy error format
          let errorMessage = `Failed to send invitation (${response.status})`;
          if (errorData.email) {
            errorMessage = errorData.email;
          } else if (errorData.error) {
            errorMessage = errorData.error;
          } else if (errorData.details) {
            errorMessage = Object.values(errorData.details)[0];
          }
          throw new Error(errorMessage);
        } catch (parseError) {
          // If we can't parse the error, use status-based messages
          if (parseError.fieldErrors || parseError.message) {
            throw parseError; // Re-throw RFC 9457 error
          }

          let errorMessage = `Failed to send invitation (${response.status})`;
          if (response.status === 400) {
            errorMessage = "Invalid email address";
          } else if (response.status === 401) {
            errorMessage = "Authentication required. Please log in.";
          } else if (response.status === 429) {
            errorMessage = "Too many requests. Please try again later.";
          } else if (response.status === 500) {
            errorMessage = "Server error - please try again later";
          }
          throw new Error(errorMessage);
        }
      }

      const result = await response.json();

      console.log("[InviteEmailAPIService] Invite email response:", {
        success: result.success,
        remainingToday: result.remaining_invites_today,
        message: result.message,
      });

      return result;
    } catch (error) {
      // Differentiate between client errors (4xx) and server errors (5xx)
      if (error.status && error.status >= 400 && error.status < 500) {
        console.warn("[InviteEmailAPIService] Send invite failed (client error):", error.message);
      } else {
        console.error("[InviteEmailAPIService] Send invite failed (server error):", error);
      }
      throw error;
    }
  }

  // Get debug information
  getDebugInfo() {
    return {
      serviceName: "InviteEmailAPIService",
      type: "authenticated_api_service",
      authRequired: true,
      supportedOperations: ["sendInviteEmail"],
      endpoints: ["/api/v1/invites/send-email"],
    };
  }
}

export default InviteEmailAPIService;
