// File: monorepo/web/maplefile-frontend/src/services/API/AuthAPIService.js
// Authentication API Service - Handles all API calls for authentication

import {
  parseRFC9457Error,
  isErrorResponse,
  logErrorDetails,
  createErrorFromProblem,
} from "../../utils/rfc9457Parser";

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL
  ? `${import.meta.env.VITE_API_BASE_URL}/api/v1`
  : "/api/v1"; // Fallback to proxy from vite config

class AuthAPIService {
  constructor() {
    console.log("[AuthAPIService] API service initialized");
  }

  // Helper method to make API requests
  async makeRequest(endpoint, options = {}) {
    const url = `${API_BASE_URL}${endpoint}`;

    const defaultOptions = {
      headers: {
        "Content-Type": "application/json",
        ...options.headers,
      },
      credentials: "include", // Include credentials for CORS
      mode: "cors", // Explicit CORS mode
    };

    const requestOptions = {
      ...defaultOptions,
      ...options,
    };

    try {
      console.log(
        `[AuthAPIService] Making ${requestOptions.method || "GET"} request to:`,
        url,
      );
      const response = await fetch(url, requestOptions);

      // Handle RFC 9457 error responses
      if (isErrorResponse(response)) {
        const errorJson = await response.json();
        const errorData = parseRFC9457Error(errorJson);
        logErrorDetails(errorData); // Log in dev mode

        const error = createErrorFromProblem(errorData);
        throw error; // Error now has fieldErrors property
      }

      const data = await response.json();
      console.log("[AuthAPIService] API Response:", data);
      return data;
    } catch (error) {
      console.error("[AuthAPIService] Request failed:", error);
      throw error;
    }
  }

  // Step 1: Request One-Time Token (OTT)
  async requestOTT(email) {
    try {
      console.log("[AuthAPIService] Requesting OTT for:", email);

      const response = await this.makeRequest("/request-ott", {
        method: "POST",
        body: JSON.stringify({
          email: email.toLowerCase().trim(),
        }),
      });

      console.log("[AuthAPIService] OTT request successful");
      return response;
    } catch (error) {
      console.error("[AuthAPIService] OTT request failed:", error);
      throw new Error(`Failed to request OTT: ${error.message}`);
    }
  }

  // Step 2: Verify One-Time Token
  async verifyOTT(email, ott) {
    try {
      console.log("[AuthAPIService] Verifying OTT for:", email);

      const response = await this.makeRequest("/verify-ott", {
        method: "POST",
        body: JSON.stringify({
          email: email.toLowerCase().trim(),
          ott: ott.trim(),
        }),
      });

      console.log("[AuthAPIService] OTT verification successful");
      return response;
    } catch (error) {
      console.error("[AuthAPIService] OTT verification failed:", error);
      throw new Error(`Failed to verify OTT: ${error.message}`);
    }
  }

  // Step 3: Complete Login
  async completeLogin(email, challengeId, decryptedChallenge) {
    try {
      console.log("[AuthAPIService] Completing login for:", email);

      const response = await this.makeRequest("/complete-login", {
        method: "POST",
        body: JSON.stringify({
          email: email.toLowerCase().trim(),
          challengeId: challengeId,
          decryptedData: decryptedChallenge,
        }),
      });

      console.log("[AuthAPIService] Login completion successful");
      return response;
    } catch (error) {
      console.error("[AuthAPIService] Login completion failed:", error);
      throw new Error(`Failed to complete login: ${error.message}`);
    }
  }

  // Token refresh endpoint
  async refreshTokens(refreshTokenValue) {
    try {
      console.log("[AuthAPIService] Refreshing tokens");

      const response = await this.makeRequest("/token/refresh", {
        method: "POST",
        body: JSON.stringify({
          value: refreshTokenValue,
        }),
      });

      console.log("[AuthAPIService] Token refresh successful");
      return response;
    } catch (error) {
      console.error("[AuthAPIService] Token refresh failed:", error);
      throw new Error(`Failed to refresh tokens: ${error.message}`);
    }
  }

  // User registration
  async registerUser(userData) {
    try {
      console.log("[AuthAPIService] Registering user");

      const response = await fetch(`${API_BASE_URL}/register`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(userData),
        credentials: "include", // Include credentials for CORS
        mode: "cors", // Explicit CORS mode
      });

      console.log(
        "[AuthAPIService] Registration response status:",
        response.status,
      );

      // Handle RFC 9457 error responses
      if (isErrorResponse(response)) {
        const errorJson = await response.json();
        const errorData = parseRFC9457Error(errorJson);
        logErrorDetails(errorData); // Log in dev mode

        const error = createErrorFromProblem(errorData);
        throw error; // Error now has fieldErrors property
      }

      const result = await response.json();
      console.log("[AuthAPIService] Registration successful");
      return result;
    } catch (error) {
      console.error("[AuthAPIService] Registration error:", error);
      throw error;
    }
  }

  // Email verification
  async verifyEmail(verificationCode) {
    try {
      console.log("[AuthAPIService] Verifying email with code");

      const response = await fetch(`${API_BASE_URL}/verify-email-code`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          code: verificationCode.trim(),
        }),
        credentials: "include", // Include credentials for CORS
        mode: "cors", // Explicit CORS mode
      });

      // Handle RFC 9457 error responses
      if (isErrorResponse(response)) {
        const errorJson = await response.json();
        const errorData = parseRFC9457Error(errorJson);
        logErrorDetails(errorData); // Log in dev mode

        const error = createErrorFromProblem(errorData);
        throw error; // Error now has fieldErrors property
      }

      const result = await response.json();
      console.log("[AuthAPIService] Email verification successful");
      return result;
    } catch (error) {
      console.error("[AuthAPIService] Email verification error:", error);
      throw error;
    }
  }

  // Get debug information
  getDebugInfo() {
    return {
      serviceName: "AuthAPIService",
      baseUrl: API_BASE_URL,
      availableEndpoints: [
        "POST /request-ott",
        "POST /verify-ott",
        "POST /complete-login",
        "POST /token/refresh",
        "POST /register",
        "POST /verify-email-code",
      ],
    };
  }
}

export default AuthAPIService;
