// File: monorepo/web/maplefile-frontend/src/services/API/User/UserLookupAPIService.js
// User Lookup API Service - Handles user public key lookup API calls with proper error handling
import { parseRFC9457Error, createErrorFromProblem } from "../../../utils/rfc9457Parser.js";
import LocalStorageService from "../../Storage/LocalStorageService.js";

class UserLookupAPIService {
  constructor() {
    this._apiClient = null;
    console.log(
      "[UserLookupAPIService] API service initialized for authenticated user lookups",
    );
  }

  // 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();
  }

  // Lookup user public key by email with proper error handling
  async lookupUser(email) {
    try {
      console.log("[UserLookupAPIService] Looking up user by email:", 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 look up users.");
      }

      // Make authenticated fetch call to handle errors properly
      const response = await fetch(
        `${apiBaseUrl}/iam/api/v1/users/lookup?email=${encodeURIComponent(sanitizedEmail)}`,
        {
          headers: {
            'Authorization': authHeader,
            'Content-Type': 'application/json',
          },
        }
      );

      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 = `Lookup failed (${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 = `Lookup failed (${response.status})`;
          if (response.status === 400) {
            errorMessage = `User not found or lookup failed for: ${sanitizedEmail}`;
          } else if (response.status === 401) {
            errorMessage = "Authentication required. Please log in to look up users.";
          } else if (response.status === 500) {
            errorMessage = "Server error - please try again later";
          }
          throw new Error(errorMessage);
        }
      }

      const user = await response.json();

      console.log("[UserLookupAPIService] User lookup successful:", {
        email: user.email,
        userId: user.user_id,
        name: user.name,
        hasPublicKey: !!user.public_key_in_base64,
        hasVerificationId: !!user.verification_id,
      });

      return user;
    } catch (error) {
      // Differentiate between client errors (4xx) and server errors (5xx)
      // Only use console.error for actual server errors (5xx)
      if (error.status && error.status >= 400 && error.status < 500) {
        console.warn("[UserLookupAPIService] User lookup failed (client error):", error.message);
      } else {
        console.error("[UserLookupAPIService] User lookup failed (server error):", error);
      }
      throw error; // Re-throw with the original message
    }
  }

  // Check if user exists (lightweight check)
  async userExists(email) {
    try {
      console.log("[UserLookupAPIService] Checking if user exists:", email);
      await this.lookupUser(email);
      return true;
    } catch (error) {
      // Handle generic "Unable to complete lookup" error as user not found
      if (
        error.message.includes("not found") ||
        error.message.includes("does not exist") ||
        error.message.includes("Unable to complete lookup") ||
        error.message.includes("lookup failed")
      ) {
        return false;
      }
      // Re-throw other errors (network, validation, auth, etc.)
      throw error;
    }
  }

  // Get debug information
  getDebugInfo() {
    return {
      serviceName: "UserLookupAPIService",
      type: "authenticated_api_service",
      authRequired: true,
      supportedOperations: ["lookupUser", "userExists"],
      endpoints: ["/iam/api/v1/users/lookup"],
    };
  }
}

export default UserLookupAPIService;
