/**
 * Get Started API Client
 *
 * API calls for the unified get-started flow
 */

import { apiClient, getDataOrThrow } from "@/core/api";
import {
  sendVerificationCodeResponseSchema,
  verifyCodeResponseSchema,
  guestEligibilityResponseSchema,
  signupWithEligibilityResponseSchema,
  type SendVerificationCodeRequest,
  type SendVerificationCodeResponse,
  type VerifyCodeRequest,
  type VerifyCodeResponse,
  type GuestEligibilityRequest,
  type GuestEligibilityResponse,
  type CompleteAccountRequest,
  type SignupWithEligibilityRequest,
  type SignupWithEligibilityResponse,
} from "@customer-portal/domain/get-started";
import {
  authResponseSchema,
  type AuthResponse,
  type AuthSession,
} from "@customer-portal/domain/auth";
import type { User } from "@customer-portal/domain/customer";

const BASE_PATH = "/api/auth/get-started";

/**
 * Response type for signup with eligibility - success case includes auth data
 */
export type SignupWithEligibilitySuccessResponse = SignupWithEligibilityResponse & {
  success: true;
  user: User;
  session: AuthSession;
};

export type SignupWithEligibilityApiResponse =
  | SignupWithEligibilityResponse
  | SignupWithEligibilitySuccessResponse;

/**
 * Send OTP verification code to email
 */
export async function sendVerificationCode(
  request: SendVerificationCodeRequest
): Promise<SendVerificationCodeResponse> {
  const response = await apiClient.POST<SendVerificationCodeResponse>(`${BASE_PATH}/send-code`, {
    body: request,
  });
  const data = getDataOrThrow(response, "Failed to send verification code");
  return sendVerificationCodeResponseSchema.parse(data);
}

/**
 * Verify OTP code and get account status
 */
export async function verifyCode(request: VerifyCodeRequest): Promise<VerifyCodeResponse> {
  const response = await apiClient.POST<VerifyCodeResponse>(`${BASE_PATH}/verify-code`, {
    body: request,
  });
  const data = getDataOrThrow(response, "Failed to verify code");
  return verifyCodeResponseSchema.parse(data);
}

/**
 * Guest eligibility check - NO OTP verification required
 *
 * Allows users to check availability without verifying email first.
 * Email verification happens later when user creates an account.
 */
export async function guestEligibilityCheck(
  request: GuestEligibilityRequest
): Promise<GuestEligibilityResponse> {
  const response = await apiClient.POST<GuestEligibilityResponse>(
    `${BASE_PATH}/guest-eligibility`,
    { body: request }
  );
  const data = getDataOrThrow(response, "Failed to submit eligibility check");
  return guestEligibilityResponseSchema.parse(data);
}

/**
 * Complete account for SF-only users
 *
 * Returns auth response with user and session.
 */
export async function completeAccount(request: CompleteAccountRequest): Promise<AuthResponse> {
  const response = await apiClient.POST<AuthResponse>(`${BASE_PATH}/complete-account`, {
    body: request,
  });
  const data = getDataOrThrow(response, "Failed to complete account");
  return authResponseSchema.parse(data);
}

/**
 * Full signup with eligibility check (inline flow)
 *
 * Creates SF Account + Case + WHMCS + Portal in one operation.
 * Returns auth data (user + session) on success.
 */
export async function signupWithEligibility(
  request: SignupWithEligibilityRequest
): Promise<SignupWithEligibilityApiResponse> {
  const response = await apiClient.POST<SignupWithEligibilityApiResponse>(
    `${BASE_PATH}/signup-with-eligibility`,
    { body: request }
  );
  const data = getDataOrThrow(response, "Failed to create account");

  // Parse base response first
  const baseResponse = signupWithEligibilityResponseSchema.parse(data);

  // If successful, parse the full auth data
  if (baseResponse.success && "user" in data && "session" in data) {
    const authData = authResponseSchema.parse({ user: data.user, session: data.session });
    return {
      ...baseResponse,
      success: true as const,
      user: authData.user,
      session: authData.session,
    };
  }

  return baseResponse;
}

/**
 * Type guard to check if signup response was successful
 */
export function isSignupSuccess(
  response: SignupWithEligibilityApiResponse
): response is SignupWithEligibilitySuccessResponse {
  return response.success === true && "user" in response && "session" in response;
}
