package com.airlock.iam.admin.domain.model.event;

import com.airlock.iam.admin.api.domain.service.user.ManagedUserRepository;
import com.airlock.iam.admin.domain.model.user.ManagedUserImpl;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.common.api.domain.model.contextdata.ContextData;
import com.airlock.iam.common.api.domain.model.user.User;
import com.airlock.iam.common.domain.service.event.LocaleProvider;
import com.airlock.iam.core.misc.util.LanguageUtils;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Provider;
import java.util.Locale;

public final class ManagedUserLocaleProvider implements LocaleProvider {
   private static final ELogger LOG = ELoggerFactory.getLogger(ManagedUserLocaleProvider.class);
   private final Provider<ManagedUserRepository> repository;
   private final String languageContextDataname;
   private final Locale defaultLocale;

   private ManagedUserLocaleProvider(Provider<ManagedUserRepository> repository, String languageContextDataname, Locale defaultLocale) {
      this.repository = repository;
      this.languageContextDataname = languageContextDataname;
      this.defaultLocale = defaultLocale;
   }

   public Locale userLocale(UserId userId) {
      return ((ManagedUserRepository)this.repository.get())
         .findById(userId)
         .or(ManagedUserImpl.userNotFound(userId, LOG))
         .<ContextData>map(User::getContextData)
         .map(contextData -> contextData.asKeyValueMap().get(this.languageContextDataname))
         .map(String::valueOf)
         .<Locale>map(LanguageUtils::getLocale)
         .orElse(this.defaultLocale);
   }

   public Locale defaultLocale() {
      return this.defaultLocale;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static ManagedUserLocaleProvider.ManagedUserLocaleProviderBuilder builder() {
      return new ManagedUserLocaleProvider.ManagedUserLocaleProviderBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class ManagedUserLocaleProviderBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Provider<ManagedUserRepository> repository;
      @SuppressFBWarnings(justification = "generated code")
      private String languageContextDataname;
      @SuppressFBWarnings(justification = "generated code")
      private Locale defaultLocale;

      @SuppressFBWarnings(justification = "generated code")
      ManagedUserLocaleProviderBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public ManagedUserLocaleProvider.ManagedUserLocaleProviderBuilder repository(Provider<ManagedUserRepository> repository) {
         this.repository = repository;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ManagedUserLocaleProvider.ManagedUserLocaleProviderBuilder languageContextDataname(String languageContextDataname) {
         this.languageContextDataname = languageContextDataname;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ManagedUserLocaleProvider.ManagedUserLocaleProviderBuilder defaultLocale(Locale defaultLocale) {
         this.defaultLocale = defaultLocale;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ManagedUserLocaleProvider build() {
         return new ManagedUserLocaleProvider(this.repository, this.languageContextDataname, this.defaultLocale);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "ManagedUserLocaleProvider.ManagedUserLocaleProviderBuilder(repository="
            + this.repository
            + ", languageContextDataname="
            + this.languageContextDataname
            + ", defaultLocale="
            + this.defaultLocale
            + ")";
      }
   }
}
