import { createFeatureSelector, createSelector } from '@ngrx/store';
import { UsersState, usersAdapter } from './users.reducer';

/** Selects the top-level users feature state. */
export const selectUsersState = createFeatureSelector<UsersState>('users');

const { selectIds, selectEntities, selectAll, selectTotal } = usersAdapter.getSelectors();

/** Selects all user entities as a flat array. */
export const selectAllUsers = createSelector(selectUsersState, selectAll);

/** Selects the user entity dictionary keyed by ID. */
export const selectUsersEntities = createSelector(selectUsersState, selectEntities);

/** Selects all user IDs. */
export const selectUsersIds = createSelector(selectUsersState, selectIds);

/** Selects the total count of users. */
export const selectUsersTotal = createSelector(selectUsersState, selectTotal);

/** Whether a user-loading operation is in progress. */
export const selectUsersLoading = createSelector(
  selectUsersState,
  (state) => state.loading
);

/** Selects the most recent users-related error message. */
export const selectUsersError = createSelector(
  selectUsersState,
  (state) => state.error
);

/** Selects the current (local) user's ID, or null. */
export const selectCurrentUserId = createSelector(
  selectUsersState,
  (state) => state.currentUserId
);

/** Selects the host's user ID. */
export const selectHostId = createSelector(
  selectUsersState,
  (state) => state.hostId
);

/** Selects all active ban entries for the current room. */
export const selectBannedUsers = createSelector(
  selectUsersState,
  (state) => state.bans
);

/** Selects the full User entity for the current (local) user. */
export const selectCurrentUser = createSelector(
  selectUsersEntities,
  selectCurrentUserId,
  (entities, currentUserId) => (currentUserId ? entities[currentUserId] : null)
);

/** Selects the full User entity for the room host. */
export const selectHost = createSelector(
  selectUsersEntities,
  selectHostId,
  (entities, hostId) => (hostId ? entities[hostId] : null)
);

/** Creates a selector that returns a single user by their ID. */
export const selectUserById = (id: string) =>
  createSelector(selectUsersEntities, (entities) => entities[id]);

/** Whether the current user is the room host. */
export const selectIsCurrentUserHost = createSelector(
  selectCurrentUserId,
  selectHostId,
  (currentUserId, hostId) => currentUserId === hostId
);

/** Whether the current user holds an elevated role (host, admin, or moderator). */
export const selectIsCurrentUserAdmin = createSelector(
  selectCurrentUser,
  (user) => user?.role === 'host' || user?.role === 'admin' || user?.role === 'moderator'
);

/** Selects users who are currently online (not offline). */
export const selectOnlineUsers = createSelector(
  selectAllUsers,
  (users) => users.filter((user) => {
    if (Array.isArray(user.presenceServerIds)) {
      return user.presenceServerIds.length > 0 || user.isOnline === true || user.status !== 'offline';
    }

    return user.status !== 'offline' || user.isOnline === true;
  })
);

/** Selects the manual status override set by the current user, or null for automatic. */
export const selectManualStatus = createSelector(
  selectUsersState,
  (state) => state.manualStatus
);

/** Creates a selector that returns users with a specific role. */
export const selectUsersByRole = (role: string) =>
  createSelector(selectAllUsers, (users) =>
    users.filter((user) => user.role === role)
  );

/** Selects all users with an elevated role (host, admin, or moderator). */
export const selectAdmins = createSelector(
  selectAllUsers,
  (users) => users.filter((user) => user.role === 'host' || user.role === 'admin' || user.role === 'moderator')
);

/** Whether the current user is the room owner (host role). */
export const selectIsCurrentUserOwner = createSelector(
  selectCurrentUser,
  (user) => user?.role === 'host'
);
