import type { SupabaseClient, User } from "@supabase/supabase-js";

/**
 * Result of auth header validation
 */
export type AuthHeaderValidationResult =
  | { success: true; token: string }
  | { success: false; error: string; statusCode: number };

/**
 * Result of user authentication
 */
export type AuthResult =
  | { success: true; user: User }
  | { success: false; error: string; statusCode: number };

/**
 * Validates the Authorization header format and extracts the Bearer token
 * @param authHeader - The Authorization header value
 * @returns Validation result with token or error
 */
export function validateAuthHeader(authHeader: string | undefined): AuthHeaderValidationResult {
  // Handle non-string inputs (runtime type safety)
  if (typeof authHeader !== "string" || !authHeader) {
    return {
      success: false,
      error: "Missing or invalid authorization header",
      statusCode: 401,
    };
  }

  if (!authHeader.startsWith("Bearer ")) {
    return {
      success: false,
      error: "Missing or invalid authorization header",
      statusCode: 401,
    };
  }

  const token = authHeader.substring(7); // Remove "Bearer " prefix

  if (!token || token.trim() === "") {
    return {
      success: false,
      error: "Missing or invalid authorization header",
      statusCode: 401,
    };
  }

  return {
    success: true,
    token,
  };
}

/**
 * Authenticates a user with Supabase using a Bearer token
 * @param supabase - Supabase client instance
 * @param token - The Bearer token to validate
 * @returns Auth result with user or error
 */
export async function authenticateUser(
  supabase: SupabaseClient,
  token: string
): Promise<AuthResult> {
  try {
    const {
      data: { user },
      error,
    } = await supabase.auth.getUser(token);

    if (error || !user) {
      return {
        success: false,
        error: "Invalid or expired token",
        statusCode: 401,
      };
    }

    return {
      success: true,
      user,
    };
  } catch {
    return {
      success: false,
      error: "Invalid or expired token",
      statusCode: 401,
    };
  }
}

/**
 * Complete authentication flow: validates header and authenticates user
 * @param authHeader - The Authorization header value
 * @param supabase - Supabase client instance
 * @returns Auth result with user or error
 */
export async function authenticateFromHeader(
  authHeader: string | undefined,
  supabase: SupabaseClient
): Promise<AuthResult> {
  const headerValidation = validateAuthHeader(authHeader);

  if (headerValidation.success) {
    return authenticateUser(supabase, headerValidation.token);
  }

  // headerValidation.success is false, so error and statusCode exist
  return {
    success: false,
    error: (headerValidation as { success: false; error: string; statusCode: number }).error,
    statusCode: (headerValidation as { success: false; error: string; statusCode: number })
      .statusCode,
  };
}
