import { create } from "zustand";
import { Platform } from "react-native";
import {
  onAuthStateChanged,
  signOut as firebaseSignOut,
  isWeb,
  getAuthInstance,
} from "../firebase";
import { UserProfile, AuthService } from "../services/authServices";
import { UserWallet } from "../services/walletService";
import { useUserProfileStore } from "./userProfileStore";
import { useTransactionStore } from "./transactionStore";
import { useUserWalletStore } from "./userWalletStore";
import { withGlobalLoading } from "./uiStore";
import { awardDailyLoginPoints } from "../services/pointsService";

// Conditionally import FCMService only for native
let FCMService: any = null;
if (Platform.OS !== "web") {
  FCMService = require("../services/fcmService").FCMService;
}

interface AuthState {
  // User state
  user: any | null;
  profile: UserProfile | null;
  wallet: UserWallet | null;

  // Loading states
  loading: boolean;
  profileLoading: boolean;
  walletLoading: boolean;

  // Error states
  profileError: string | null;
  walletError: string | null;

  // Phone authentication state
  phoneSessionInfo: string | null;
  phoneConfirmationResult: any | null;
  phoneLoading: boolean;
  phoneError: string | null;

  // Computed values
  formattedBalance: string;

  // Actions
  setUser: (user: any | null) => void;
  setProfile: (profile: UserProfile | null) => void;
  setWallet: (wallet: UserWallet | null) => void;
  setLoading: (loading: boolean) => void;
  setProfileLoading: (loading: boolean) => void;
  setWalletLoading: (loading: boolean) => void;
  setProfileError: (error: string | null) => void;
  setWalletError: (error: string | null) => void;
  setFormattedBalance: (balance: string) => void;

  // Phone auth setters
  setPhoneSessionInfo: (sessionInfo: string | null) => void;
  setPhoneConfirmationResult: (confirmationResult: any | null) => void;
  setPhoneLoading: (loading: boolean) => void;
  setPhoneError: (error: string | null) => void;
  clearPhoneAuth: () => void;

  // Auth actions
  signOut: () => Promise<void>;
  refreshProfile: () => Promise<void>;
  refreshWallet: () => Promise<void>;

  // Initialize auth listener
  initializeAuth: () => () => void;
}

export const useAuthStore = create<AuthState>((set, get) => ({
  // Initial state
  user: null,
  profile: null,
  wallet: null,
  loading: true,
  profileLoading: false,
  walletLoading: false,
  profileError: null,
  walletError: null,
  phoneSessionInfo: null,
  phoneConfirmationResult: null,
  phoneLoading: false,
  phoneError: null,
  formattedBalance: "0.00",

  // Setters
  setUser: (user) => set({ user }),
  setProfile: (profile) => set({ profile }),
  setWallet: (wallet) => set({ wallet }),
  setLoading: (loading) => set({ loading }),
  setProfileLoading: (profileLoading) => set({ profileLoading }),
  setWalletLoading: (walletLoading) => set({ walletLoading }),
  setProfileError: (error) => set({ profileError: error }),
  setWalletError: (error) => set({ walletError: error }),
  setFormattedBalance: (formattedBalance) => set({ formattedBalance }),

  // Phone auth setters
  setPhoneSessionInfo: (phoneSessionInfo) => set({ phoneSessionInfo }),
  setPhoneConfirmationResult: (phoneConfirmationResult) =>
    set({ phoneConfirmationResult }),
  setPhoneLoading: (phoneLoading) => set({ phoneLoading }),
  setPhoneError: (phoneError) => set({ phoneError }),

  // Phone auth actions
  clearPhoneAuth: () =>
    set({
      phoneSessionInfo: null,
      phoneConfirmationResult: null,
      phoneLoading: false,
      phoneError: null,
    }),

  // Auth actions
  signOut: async () => {
    // Get current user from our abstracted firebase module
    const currentUser = getAuthInstance().currentUser;

    // If there is no current Firebase user (common in dev with mocked flows),
    // just clear local state and exit without throwing.
    if (!currentUser) {
      console.warn(
        "AuthStore.signOut called with no current Firebase user; clearing local state only"
      );
      get().setUser(null);
      get().clearPhoneAuth();
      useUserProfileStore.getState().clearAll();
      useTransactionStore.getState().clearAll();
      useUserWalletStore.getState().clearAll();
      return;
    }

    try {
      const uid = get().user?.uid;

      // Remove FCM token from Firestore before signing out (native only)
      if (uid && FCMService && Platform.OS !== "web") {
        try {
          await FCMService.removeTokenFromFirestore(uid);
          FCMService.cleanup();
        } catch (fcmError) {
          console.error("Error removing FCM token on sign out:", fcmError);
        }
      }

      await withGlobalLoading(async () => {
        // Sign out from Google if signed in with Google
        await AuthService.signOutFromGoogle();
        // Sign out from Firebase
        await firebaseSignOut();
      });

      get().clearPhoneAuth();
      useUserProfileStore.getState().clearAll();
      useTransactionStore.getState().clearAll();
      useUserWalletStore.getState().clearAll();
    } catch (error) {
      console.error("Error signing out:", error);
      throw error;
    }
  },

  refreshProfile: async () => {
    const uid = get().user?.uid;
    if (!uid) {
      console.warn(
        "AuthStore.refreshProfile called without an authenticated user"
      );
      return;
    }

    const profileStore = useUserProfileStore.getState();
    profileStore.ensureSubscription(uid);
    await withGlobalLoading(() => profileStore.refreshProfile(uid));
  },

  refreshWallet: async () => {
    const uid = get().user?.uid;
    if (!uid) {
      console.warn(
        "AuthStore.refreshWallet called without an authenticated user"
      );
      return;
    }

    const walletStore = useUserWalletStore.getState();
    walletStore.ensureSubscription(uid);
    await withGlobalLoading(() => walletStore.refreshWallet(uid));
  },

  // Initialize auth listener
  initializeAuth: () => {
    console.log("AuthStore: Initializing auth listener");
    const unsubscribe = onAuthStateChanged((fbUser: any) => {
      // In dev, if we've explicitly set a fake emulator user, don't let
      // Firebase auth (which will report null) wipe it out.
      if (__DEV__) {
        const current = get().user;
        if (current?.uid === "dev-emulator-user") {
          if (get().loading) {
            set({ loading: false });
          }
          return;
        }
      }

      console.log("AuthStore: Auth state changed, user:", fbUser?.uid);
      set({ user: fbUser || null, loading: false });
      if (fbUser) {
        awardDailyLoginPoints().catch((error) => {
          console.warn(
            "[AuthStore] Failed to maybe award daily login points",
            error
          );
        });
      }
    });
    return unsubscribe;
  },
}));
