package com.airlock.iam.admin.infrastructure.factory.prot;

import com.airlock.iam.admin.application.configuration.users.UsersConfiguration;
import com.airlock.iam.admin.domain.model.user.UserSpecificSettings;
import com.airlock.iam.admin.domain.service.access.AdminappAccessController;
import com.airlock.iam.admin.infrastructure.service.ProfileItems;
import com.airlock.iam.base.api.infrastructure.plugin.PluginConfigToLogic;
import com.airlock.iam.common.api.domain.model.authentication.Authentee;
import com.airlock.iam.common.application.configuration.userprofile.UserProfileItemConfig;
import com.airlock.iam.common.domain.model.user.profileitems.UserProfileItemDetails;
import com.airlock.iam.common.domain.model.user.profileitems.UserProfileItems;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.servlet.RequestScoped;
import jakarta.inject.Named;
import jakarta.inject.Provider;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class UserProfileItemsModule extends PrivateModule {
   @RequestScoped
   @Provides
   @Exposed
   UserProfileItems provide(
      Optional<UsersConfiguration> usersConfiguration,
      UserSpecificSettings userSpecificSettings,
      @Named("authentee") Provider<Optional<Authentee>> admin,
      AdminappAccessController accessController,
      PluginConfigToLogic toLogic
   ) {
      return usersConfiguration.isEmpty()
         ? UserProfileItems.empty()
         : new UserProfileItems(
            this.transform(userSpecificSettings, accessController, usersConfiguration.get().getColumnsInUserList(), toLogic),
            this.transform(userSpecificSettings, accessController, userSpecificSettings.getRowsOnUserDetailPage(), toLogic)
         );
   }

   private List<UserProfileItemDetails> transform(
      UserSpecificSettings userSpecificSettings,
      AdminappAccessController accessController,
      List<UserProfileItemConfig> profileItems,
      PluginConfigToLogic toLogic
   ) {
      List<UserProfileItemConfig> filteredItems = profileItems.stream()
         .filter(item -> accessController.isContextDataColumnVisible(item.getPropertyName()))
         .collect(Collectors.toList());
      return ProfileItems.asProfileItemDetails(filteredItems, this.editableFunction(accessController, userSpecificSettings), toLogic);
   }

   private Predicate<UserProfileItemConfig> editableFunction(AdminappAccessController accessController, UserSpecificSettings userSpecificSettings) {
      return item -> item.isModifiable() && userSpecificSettings.isEditable() && accessController.isContextDataColumnEditable(item.getPropertyName());
   }

   protected void configure() {
   }
}
