import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";
import { loginWithEmail, logout, getCurrentUser } from "../../services/authService";
import { fetchUserData } from "../../services/firestoreService";
import type { User } from "firebase/auth";

export interface AuthUser {
  uid: string;
  email: string | null;
  displayName: string | null;
  photoURL: string | null;
  userRole?: "admin" | "client" | "vendor" | "ADMIN" | "CLIENT" | "VENDOR";
}

interface AuthState {
  user: AuthUser | null;
  isAuthenticated: boolean;
  status: "idle" | "loading" | "succeeded" | "failed";
  error: string | null;
  isInitialized: boolean; // Track whether initial auth check has completed
}

const initialState: AuthState = {
  user: null,
  isAuthenticated: false,
  status: "idle",
  error: null,
  isInitialized: false, // Start as false until initial auth check completes
};

/**
 * Async thunk for user login
 * Fetches user data including role from Firestore after authentication
 */
export const loginUser = createAsyncThunk(
  "auth/loginUser",
  async ({ email, password }: { email: string; password: string }, { rejectWithValue }) => {
    const result = await loginWithEmail(email, password);

    if (!result.success) {
      return rejectWithValue(result.error);
    }

    const firebaseUser = result.user as User;
    
    // Fetch user role from backend (DataConnect) or fallback (Firestore)
    let userRole: AuthUser['userRole'] = undefined;
    if(userRole === undefined){
      userRole = "client"; // Default to 'client' if role is missing
    }
    try {
      const userData = await fetchUserData(firebaseUser.uid);
      if (userData && userData.userRole) {
        userRole = userData.userRole as AuthUser['userRole'];
      }
    } catch (error) {
      console.error("Failed to fetch user role:", error);
      // Do not assign a frontend default — treat missing role as undefined
    }
    return {
      uid: firebaseUser.uid,
      email: firebaseUser.email,
      displayName: firebaseUser.displayName,
      photoURL: firebaseUser.photoURL,
      userRole,
    };
  }
);

/**
 * Async thunk for user logout
 */
export const logoutUser = createAsyncThunk("auth/logoutUser", async (_, { rejectWithValue }) => {
  const result = await logout();

  if (!result.success) {
    return rejectWithValue(result.error);
  }

  return null;
});

/**
 * Async thunk to check if user is already logged in
 * Fetches user role from Firestore on app initialization
 */
export const checkAuthStatus = createAsyncThunk("auth/checkAuthStatus", async () => {
  const currentUser = getCurrentUser();

  if (currentUser) {
    // Fetch user role from backend (DataConnect) or fallback (Firestore)
    let userRole: AuthUser['userRole'] = undefined;
    try {
      const userData = await fetchUserData(currentUser.uid);
      if (userData && userData.userRole) {
        console.log("User data fetched during auth check:", userData);
        userRole = userData.userRole as AuthUser['userRole'];
        console.log("Fetched user role:", userRole);
      }
    } catch (error) {
      console.error("Failed to fetch user role:", error);
      // Do not apply a frontend default role
    }

    return {
      uid: currentUser.uid,
      email: currentUser.email,
      displayName: currentUser.displayName,
      photoURL: currentUser.photoURL,
      userRole,
    };
  }

  return null;
});

const authSlice = createSlice({
  name: "auth",
  initialState,
  reducers: {
    clearError: (state) => {
      state.error = null;
    },
    setUserRole: (state, action: PayloadAction<"admin" | "client" | "vendor">) => {
      if (state.user) {
        state.user.userRole = action.payload;
      }
    },
  },
  extraReducers: (builder) => {
    // Login thunk
    builder
      .addCase(loginUser.pending, (state) => {
        state.status = "loading";
        state.error = null;
      })
      .addCase(loginUser.fulfilled, (state, action) => {
        state.status = "succeeded";
        state.isAuthenticated = true;
        state.user = action.payload;
        state.error = null;
      })
      .addCase(loginUser.rejected, (state, action) => {
        state.status = "failed";
        state.error = action.payload as string;
        state.isAuthenticated = false;
      });

    // Logout thunk
    builder
      .addCase(logoutUser.fulfilled, (state) => {
        state.user = null;
        state.isAuthenticated = false;
        state.status = "idle";
        state.error = null;
      })
      .addCase(logoutUser.rejected, (state, action) => {
        state.error = action.payload as string;
      });

    // Check auth status thunk
    builder
      .addCase(checkAuthStatus.pending, (state) => {
        state.status = "loading";
      })
      .addCase(checkAuthStatus.fulfilled, (state, action) => {
        if (action.payload) {
          state.user = action.payload;
          state.isAuthenticated = true;
        } else {
          state.user = null;
          state.isAuthenticated = false;
        }
        state.status = "idle";
        state.isInitialized = true; // Mark initialization as complete
      })
      .addCase(checkAuthStatus.rejected, (state) => {
        state.isInitialized = true; // Mark initialization as complete even on error
        state.isAuthenticated = false;
      });
  },
});

export const { clearError, setUserRole } = authSlice.actions;
export default authSlice.reducer;
