import { signInWithPopup, signOut, User, UserCredential } from "firebase/auth";
import { auth, googleProvider, twitterProvider } from "../config/firebase";
import { getSocialAccount, SocialLoginResponse } from "./services";

export interface GoogleAuthResult {
  success: boolean;
  user?: SocialLoginResponse;
  error?: string;
}

export interface TwitterAuthResult {
  success: boolean;
  user?: SocialLoginResponse;
  error?: string;
}

/**
 * Sign in with Google using Firebase Auth
 */
export const signInWithGoogle = async (
  apiKey: string
): Promise<GoogleAuthResult> => {
  try {
    const result: UserCredential = await signInWithPopup(auth, googleProvider);
    const user = result.user;

    // Call the social account API with the Google user data
    const socialAccountResult = await getSocialAccount(
      { googleUser: user },
      apiKey
    );

    return {
      success: true,
      // @ts-ignore
      user: { ...socialAccountResult, token: user.accessToken },
    };
  } catch (error: any) {
    console.error("Error signing in with Google:", error);

    let errorMessage = "Failed to sign in with Google";

    // Handle specific Firebase Auth errors
    switch (error.code) {
      case "auth/popup-closed-by-user":
        errorMessage = "Sign-in cancelled by user";
        break;
      case "auth/popup-blocked":
        errorMessage = "Popup was blocked. Please allow popups for this site";
        break;
      case "auth/cancelled-popup-request":
        errorMessage = "Sign-in request was cancelled";
        break;
      case "auth/network-request-failed":
        errorMessage = "Network error. Please check your connection";
        break;
      default:
        errorMessage = error.message || "Failed to sign in with Google";
    }

    return {
      success: false,
      error: errorMessage,
    };
  }
};

/**
 * Sign in with Twitter using Firebase Auth
 */
export const signInWithTwitter = async (
  apiKey: string
): Promise<TwitterAuthResult> => {
  try {
    const result: UserCredential = await signInWithPopup(auth, twitterProvider);
    const user = result.user;

    console.log("user", user);

    // Extract Twitter user data
    const twitterUser = {
      uid: user.uid,
      // @ts-ignore
      username: user.reloadUserInfo?.providerUserInfo?.[0]?.screenName || "",
      name: user.displayName || undefined,
      profile_image_url: user.photoURL || undefined,
      email: user.email || undefined,
    };

    // Call the social account API with the Twitter user data
    const socialAccountResult = await getSocialAccount({ twitterUser }, apiKey);

    return {
      success: true,
      // @ts-ignore
      user: { ...socialAccountResult, token: user.accessToken },
    };
  } catch (error: any) {
    console.error("Error signing in with Twitter:", error);

    let errorMessage = "Failed to sign in with Twitter";

    // Handle specific Firebase Auth errors
    switch (error.code) {
      case "auth/popup-closed-by-user":
        errorMessage = "Sign-in cancelled by user";
        break;
      case "auth/popup-blocked":
        errorMessage = "Popup was blocked. Please allow popups for this site";
        break;
      case "auth/cancelled-popup-request":
        errorMessage = "Sign-in request was cancelled";
        break;
      case "auth/network-request-failed":
        errorMessage = "Network error. Please check your connection";
        break;
      case "auth/account-exists-with-different-credential":
        errorMessage =
          "An account already exists with the same email address but different sign-in credentials";
        break;
      default:
        errorMessage = error.message || "Failed to sign in with Twitter";
    }

    return {
      success: false,
      error: errorMessage,
    };
  }
};

/**
 * Sign out the current user
 */
export const signOutUser = async (): Promise<boolean> => {
  try {
    await signOut(auth);
    return true;
  } catch (error) {
    console.error("Error signing out:", error);
    return false;
  }
};

/**
 * Get the current authenticated user
 */
export const getCurrentUser = (): User | null => {
  return auth.currentUser;
};

/**
 * Listen to authentication state changes
 */
export const onAuthStateChange = (callback: (user: User | null) => void) => {
  return auth.onAuthStateChanged(callback);
};
