import { createAuthClient } from "better-auth/react";
import { toast } from "sonner";
import { organizationClient } from "better-auth/client/plugins";
import { stripeClient } from "@better-auth/stripe/client";

/**
 * Better Auth Client Configuration
 *
 * Best practices:
 * - Don't set baseURL (use relative paths for same-origin cookies)
 * - Always include credentials
 * - Handle errors gracefully
 * - Use plugins as needed
 */
export const authClient = createAuthClient({
  // Use relative paths for same-origin requests
  // baseURL is only needed if auth API is on different domain

  fetchOptions: {
    credentials: "include", // Include cookies in all requests
    onError: async (context) => {
      const { response, error } = context;

      // Rate limiting
      if (response?.status === 429) {
        const retryAfter = response.headers.get("X-Retry-After");
        toast.error(
          `Too many requests. Please try again in ${retryAfter} seconds.`
        );
        return;
      }

      // Network errors
      if (!response) {
        toast.error("Network error. Please check your connection.");
        return;
      }

      // Other errors
      console.error("Auth error:", error);
    },
  },

  // Plugins
  plugins: [
    organizationClient(),
    stripeClient({
      subscription: true,
    }),
  ],
});
/**
 * Export commonly used hooks and methods
 */
export const { useSession, signIn, signOut, signUp } = authClient;

/**
 * Resend verification email
 * @param email - User's email address
 */
export const resendVerificationEmail = async (email: string) => {
  const res = await fetch("/api/auth/resend-verification", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email }),
  });
  if (!res.ok) {
    throw new Error("Failed to resend verification email.");
  }
  return res.json();
};
/**
 * Sign in with email and password
 * @param email - User's email address
 * @param password - User's password
 */
export const signInWithEmail = async (email: string, password: string) => {
  const data = await authClient.signIn.email(
    {
      email,
      password,
    },
    {
      onError: (ctx) => {
        // Handle the error
        if (ctx.error.status === 403) {
          throw new Error("Please verify your email address");
        }
        throw new Error(ctx.error.message);
      },
    }
  );
  return data;
};

/**
 * Sign in with Google using OAuth
 * This will redirect the user to Google's consent screen
 */
export const signInWithGoogle = async () => {
  const data = await authClient.signIn.social({
    provider: "google",
  });
  return data;
};

/**
 * Sign in with Google using ID Token
 * Useful when you already have the Google ID Token from client-side
 * @param token - Google ID Token
 * @param accessToken - Google Access Token (optional)
 */
export const signInWithGoogleIdToken = async (
  token: string,
  accessToken?: string
) => {
  const data = await authClient.signIn.social({
    provider: "google",
    idToken: {
      token,
      accessToken,
    },
  });
  return data;
};

/**
 * Request additional Google scopes (e.g., Google Drive, Gmail)
 * @param scopes - Array of Google API scopes to request
 */
export const requestAdditionalGoogleScopes = async (scopes: string[]) => {
  await authClient.linkSocial({
    provider: "google",
    scopes,
  });
};
