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

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

/**
 * Sign in with custom token and get Firebase ID token and refresh token
 */
export const signInWithCustomTokenAndGetIdToken = async (
  customToken: string
): Promise<{
  success: boolean;
  idToken?: string;
  refreshToken?: string;
  error?: string;
}> => {
  try {
    const userCredential = await signInWithCustomToken(auth, customToken);
    const user = userCredential.user;

    // Get the ID token for API calls
    const idToken = await user.getIdToken();

    // Get the refresh token
    const refreshToken = user.refreshToken;

    return {
      success: true,
      idToken,
      refreshToken,
    };
  } catch (error: any) {
    console.error("Error signing in with custom token:", error);

    let errorMessage = "Failed to sign in with custom token";

    // Handle specific Firebase Auth errors
    switch (error.code) {
      case "auth/invalid-custom-token":
        errorMessage = "Invalid custom token";
        break;
      case "auth/custom-token-mismatch":
        errorMessage = "Custom token mismatch";
        break;
      case "auth/network-request-failed":
        errorMessage = "Network error. Please check your connection";
        break;
      default:
        errorMessage = error.message || "Failed to sign in with custom token";
    }

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

/**
 * 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
    );

    console.log("socialAccountResult >>>>>", user);
    return {
      success: true,
      // @ts-ignore
      user: {
        ...socialAccountResult,
        // @ts-ignore
        accessToken: result.user.accessToken,
        refreshToken: result.user.refreshToken,
      },
    };
  } 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,
    };
  }
};

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

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

    // Construct the twitterUser object as required
    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,
        // @ts-ignore
        accessToken: result.user.accessToken,
        refreshToken: result.user.refreshToken,
      },
    };
  } catch (error: any) {
    console.error("Error signing in with Twitter/X:", error);

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

    // 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 Twitter/X";
    }

    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);
};
