/**
 * Auth Services - Platform-aware authentication
 * Works on both native (Android/iOS) and web platforms
 */
import { Platform } from "react-native";
import {
  signInWithGoogle as firebaseSignInWithGoogle,
  signOutFromGoogle as firebaseSignOutFromGoogle,
  signInWithPhoneNumber as firebaseSignInWithPhoneNumber,
  createUserWithEmailAndPassword as firebaseCreateUserWithEmailAndPassword,
  signInWithEmailAndPassword as firebaseSignInWithEmailAndPassword,
  collection,
  doc,
  FieldValue,
  isWeb,
} from "../firebase";
import { formatPhoneNumber } from "../utils/phoneUtils";
import { useUserProfileStore } from "../stores/userProfileStore";
import { withGlobalLoading } from "../stores/uiStore";

// Types
interface PhoneAuthResult {
  confirmationResult?: any;
  error?: string;
}

interface OTPVerificationResult {
  user: any | null;
  error?: string;
}

interface GoogleSignInResult {
  user: any | null;
  isNewUser: boolean;
  error?: string;
}

export interface UserLinkedAccount {
  id: string;
  bankId: string;
  bankName: string;
  accountNumber: string;
  isDefault: boolean;
}

export interface UserProfile {
  uid: string;
  email: string;
  fullName: string;
  phoneNumber?: string;
  address?: string;
  pin?: string;
  signupType?: "phone" | "google";
  photoUrl?: string;
  fanNumber?: string;
  tin?: string;
  businessType?: string;
  nationalIdUrl?: string;
  businessLicenseUrl?: string;
  linkedAccounts?: UserLinkedAccount[];
  createdAt: any;
  updatedAt: any;
}

export class AuthService {
  // Google Sign-In - Platform aware
  static async signInWithGoogle(): Promise<GoogleSignInResult> {
    try {
      const result = await firebaseSignInWithGoogle();

      if (result.error) {
        return { user: null, isNewUser: false, error: result.error };
      }

      console.log(
        "Google Sign-In successful, user:",
        result.user?.uid,
        "isNewUser:",
        result.isNewUser
      );

      // Log ID token if available (for debugging / backend integration)
      try {
        if (
          result.user &&
          typeof (result.user as any).getIdToken === "function"
        ) {
          const idToken = await (result.user as any).getIdToken();
          console.log("GOOGLE SIGN-IN ID TOKEN:", idToken);
        }
      } catch (tokenError) {
        console.warn("Failed to get Google ID token:", tokenError);
      }
      return result;
    } catch (error: any) {
      console.error("Google Sign-In error:", error);
      return {
        user: null,
        isNewUser: false,
        error: error.message || "Google Sign-In failed",
      };
    }
  }

  // Sign out from Google
  static async signOutFromGoogle(): Promise<void> {
    try {
      await firebaseSignOutFromGoogle();
    } catch (error) {
      console.error("Google Sign-Out error:", error);
    }
  }

  // Phone number authentication - send OTP
  static async sendOTP(phoneNumber: string): Promise<PhoneAuthResult> {
    try {
      // Validate and format phone number
      const formattedPhoneNumber = formatPhoneNumber(phoneNumber);
      console.log("FORMATTED PHONE NUMBER:", formattedPhoneNumber);

      if (!formattedPhoneNumber) {
        return {
          error: "Invalid phone number format. Please use format: +1234567890",
        };
      }

      console.log("Sending OTP to:", formattedPhoneNumber);

      // Web requires reCAPTCHA initialization first
      if (isWeb) {
        // Check if reCAPTCHA container exists
        const recaptchaContainer = document.getElementById(
          "recaptcha-container"
        );
        if (!recaptchaContainer) {
          console.warn(
            "reCAPTCHA container not found. Phone auth may not work."
          );
          return {
            error:
              "Phone authentication not available. Please use Google Sign-In.",
          };
        }

        // Initialize reCAPTCHA if needed
        const { initRecaptcha } = await import("../firebase/firebase.web");
        await initRecaptcha("recaptcha-container");
      }

      const confirmationResult = await firebaseSignInWithPhoneNumber(
        formattedPhoneNumber
      );
      return { confirmationResult };
    } catch (error) {
      console.error("Phone auth error:", error);
      return {
        error: error instanceof Error ? error.message : "Failed to send OTP",
      };
    }
  }

  // Verify OTP code
  static async verifyOTP(
    confirmationResult: any,
    code: string
  ): Promise<OTPVerificationResult> {
    try {
      const result = await confirmationResult.confirm(code);
      const user = result?.user ?? null;
      if (user) {
        console.log("PHONE AUTH SUCCESS, UID:", user.uid);
        try {
          if (typeof (user as any).getIdToken === "function") {
            const idToken = await (user as any).getIdToken();
            console.log("PHONE AUTH ID TOKEN:", idToken);
          }
        } catch (tokenError) {
          console.warn("Failed to get phone auth ID token:", tokenError);
        }
      }
      return { user };
    } catch (error) {
      console.error("OTP verification error:", error);
      return {
        user: null,
        error:
          error instanceof Error ? error.message : "Invalid verification code",
      };
    }
  }

  // Update User Profile
  static async updateUserProfile(
    uid: string,
    profileData: {
      fullName?: string;
      phoneNumber?: string;
      address?: string;
      pin?: string;
      photoUrl?: string;
      fanNumber?: string;
      tin?: string;
      businessType?: string;
      nationalIdUrl?: string;
      businessLicenseUrl?: string;
      linkedAccounts?: UserLinkedAccount[];
    }
  ): Promise<{ success: boolean; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        const userDocRef = doc("users", uid);

        const updateData: any = {
          ...profileData,
          updatedAt: FieldValue.serverTimestamp(),
        };

        // Remove undefined values
        Object.keys(updateData).forEach((key) => {
          if (updateData[key] === undefined) {
            delete updateData[key];
          }
        });

        console.log("[AuthService.updateUserProfile] Updating user profile", {
          uid,
          updateData,
        });

        await userDocRef.update(updateData);
        console.log(
          "[AuthService.updateUserProfile] Profile updated successfully"
        );

        try {
          await useUserProfileStore.getState().invalidateProfile(uid);
        } catch (cacheError) {
          console.warn(
            "Failed to refresh user profile cache after update",
            cacheError
          );
        }

        return { success: true };
      } catch (error) {
        console.error(
          "[AuthService.updateUserProfile] Profile update error for uid",
          uid,
          error
        );
        return {
          success: false,
          error:
            error instanceof Error ? error.message : "Failed to update profile",
        };
      }
    });
  }

  // Check if user profile exists in Firestore
  static async checkUserProfileExists(uid: string): Promise<boolean> {
    try {
      const userDocRef = doc("users", uid);
      const userDoc = await userDocRef.get();
      // Handle both boolean and function forms of exists
      const existsValue = userDoc.exists;
      return typeof existsValue === "function" ? existsValue() : !!existsValue;
    } catch (error) {
      console.error("Error checking user profile:", error);
      return false;
    }
  }

  // Create user profile in Firestore
  static async createUserProfile(
    uid: string,
    profileData: {
      fullName: string;
      phoneNumber?: string;
      address?: string;
      email?: string;
      pin?: string;
      signupType?: "phone" | "google" | "email";
      createdAt: Date;
      updatedAt: Date;
      photoUrl?: string;
    }
  ): Promise<void> {
    return withGlobalLoading(async () => {
      try {
        console.log("Creating user profile in Firestore for UID:", uid);
        const userProfile: UserProfile = {
          uid: uid,
          email: profileData.email || "",
          fullName: profileData.fullName,
          phoneNumber: profileData.phoneNumber || "",
          address: profileData.address || "",
          pin: profileData.pin || "",
          signupType: profileData.signupType || "phone",
          photoUrl: profileData.photoUrl || "",
          createdAt: FieldValue.serverTimestamp(),
          updatedAt: FieldValue.serverTimestamp(),
        };

        const userRef = doc("users", uid);
        await userRef.set(userProfile);
        console.log("User profile created successfully in Firestore");

        try {
          await useUserProfileStore.getState().invalidateProfile(uid);
        } catch (cacheError) {
          console.warn(
            "Failed to refresh user profile cache after creation",
            cacheError
          );
        }
      } catch (error) {
        console.error("Error creating user profile:", error);
        throw error;
      }
    });
  }

  // Agent Sign Up with Email/Password
  static async signUpAgent(
    email: string,
    password: string
  ): Promise<{ user: any | null; error?: string }> {
    try {
      const result = await firebaseCreateUserWithEmailAndPassword(
        email,
        password
      );

      if (result.error) {
        return { user: null, error: result.error };
      }

      if (!result.user) {
        return { user: null, error: "Failed to create user account" };
      }

      // Check if agent exists in agents collection
      const agentDocRef = doc("agents", result.user.uid);
      const agentDoc = await agentDocRef.get();
      const agentExists = agentDoc.exists;

      if (!agentExists) {
        // If agent doesn't exist, create agent document
        await agentDocRef.set({
          uid: result.user.uid,
          email: email,
          createdAt: FieldValue.serverTimestamp(),
          updatedAt: FieldValue.serverTimestamp(),
        });
      }

      console.log("Agent signup successful, UID:", result.user.uid);
      return { user: result.user };
    } catch (error: any) {
      console.error("Agent signup error:", error);
      return {
        user: null,
        error: error.message || "Failed to sign up agent",
      };
    }
  }

  // Agent Sign In with Email/Password
  static async signInAgent(
    email: string,
    password: string
  ): Promise<{ user: any | null; error?: string }> {
    try {
      console.log("Agent signin attempt for email:", email);
      const result = await firebaseSignInWithEmailAndPassword(email.trim(), password);

      if (result.error) {
        console.error("Firebase signin error:", result.error);
        // Map common Firebase errors to user-friendly messages
        let errorMessage = result.error;
        if (result.error.includes("auth/wrong-password") || result.error.includes("auth/invalid-credential")) {
          errorMessage = "Invalid email or password";
        } else if (result.error.includes("auth/user-not-found")) {
          errorMessage = "No account found with this email";
        } else if (result.error.includes("auth/invalid-email")) {
          errorMessage = "Invalid email address";
        } else if (result.error.includes("auth/too-many-requests")) {
          errorMessage = "Too many failed attempts. Please try again later";
        }
        return { user: null, error: errorMessage };
      }

      if (!result.user) {
        console.error("No user returned from Firebase signin");
        return { user: null, error: "Failed to sign in" };
      }

      console.log("Firebase signin successful, UID:", result.user.uid);

      // Check if agent exists in agents collection
      const agentDocRef = doc("agents", result.user.uid);
      const agentDoc = await agentDocRef.get();
      const agentExists = typeof agentDoc.exists === "function" ? agentDoc.exists() : !!agentDoc.exists;

      if (!agentExists) {
        console.log("Agent document not found, creating it automatically");
        // Create agent document if it doesn't exist
        try {
          await agentDocRef.set({
            uid: result.user.uid,
            email: email.trim(),
            createdAt: FieldValue.serverTimestamp(),
            updatedAt: FieldValue.serverTimestamp(),
          });
          console.log("Agent document created successfully");
        } catch (createError) {
          console.error("Error creating agent document:", createError);
          // Still allow signin even if document creation fails
        }
      } else {
        console.log("Agent document exists");
      }

      console.log("Agent signin successful, UID:", result.user.uid);
      return { user: result.user };
    } catch (error: any) {
      console.error("Agent signin error:", error);
      let errorMessage = error.message || "Failed to sign in agent";
      // Map common Firebase errors
      if (errorMessage.includes("auth/wrong-password") || errorMessage.includes("auth/invalid-credential")) {
        errorMessage = "Invalid email or password";
      } else if (errorMessage.includes("auth/user-not-found")) {
        errorMessage = "No account found with this email";
      }
      return {
        user: null,
        error: errorMessage,
      };
    }
  }

  // Check if agent exists in agents collection
  static async checkAgentExists(uid: string): Promise<boolean> {
    try {
      const agentDocRef = doc("agents", uid);
      const agentDoc = await agentDocRef.get();
      const existsValue = agentDoc.exists;
      return typeof existsValue === "function" ? existsValue() : !!existsValue;
    } catch (error) {
      console.error("Error checking agent:", error);
      return false;
    }
  }
}

export default AuthService;
