package com.airlock.iam.admin.infrastructure.resource.auth;

import com.airlock.iam.admin.application.service.settings.AdminappCustomUrlSettings;
import com.airlock.iam.admin.application.service.settings.RedirectSettings;
import com.airlock.iam.admin.domain.model.system.IamInstance;
import com.airlock.iam.admin.infrastructure.transfer.request.UrlValidationRequest;
import com.airlock.iam.admin.infrastructure.transfer.response.AdminappLanguageSettingsData;
import com.airlock.iam.admin.infrastructure.transfer.response.CustomUrlData;
import com.airlock.iam.admin.infrastructure.transfer.response.DynamicUrlValidation;
import com.airlock.iam.admin.infrastructure.transfer.response.IamInstanceData;
import com.airlock.iam.common.application.locale.LocalePreferenceConfiguration;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;
import ma.glasnost.orika.MapperFacade;

@Path("/settings")
public class AdminappSettingsResource {
   private final Provider<MapperFacade> mapper;
   private final Provider<IamInstance> iamInstance;
   private final Provider<LocalePreferenceConfiguration> languageSettings;
   private final Provider<AdminappCustomUrlSettings> customUrlSettings;
   private final Provider<RedirectSettings> redirectSettings;

   @Inject
   public AdminappSettingsResource(
      Provider<MapperFacade> mapper,
      Provider<IamInstance> iamInstance,
      Provider<LocalePreferenceConfiguration> languageSettings,
      Provider<AdminappCustomUrlSettings> customUrlSettings,
      Provider<RedirectSettings> redirectSettings
   ) {
      this.mapper = mapper;
      this.iamInstance = iamInstance;
      this.languageSettings = languageSettings;
      this.customUrlSettings = customUrlSettings;
      this.redirectSettings = redirectSettings;
   }

   @ApiResponse(
      description = "Retrieved settings instance data.",
      responseCode = "200",
      content = {
            @Content(mediaType = "application/json;qs=0.9", schema = @Schema(implementation = IamInstanceData.class)),
            @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = IamInstanceData.class)),
            @Content(mediaType = "application/json", schema = @Schema(implementation = IamInstanceData.class))
      }
   )
   @Path("/instance")
   @GET
   @Operation(extensions = @Extension(properties = @ExtensionProperty(name = "x-internal", value = "true")))
   @Consumes("application/json")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response retrieveInstance() {
      IamInstanceData data = (IamInstanceData)((MapperFacade)this.mapper.get()).map((IamInstance)this.iamInstance.get(), IamInstanceData.class);
      return Response.ok().entity(data).build();
   }

   @ApiResponse(
      description = "Retrieved language settings.",
      responseCode = "200",
      content = @Content(mediaType = "application/json", schema = @Schema(implementation = AdminappLanguageSettingsData.class))
   )
   @Path("/languages")
   @GET
   @Operation(extensions = @Extension(properties = @ExtensionProperty(name = "x-internal", value = "true")))
   @Consumes("application/json")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response retrieveLanguages() {
      AdminappLanguageSettingsData data = (AdminappLanguageSettingsData)((MapperFacade)this.mapper.get())
         .map((LocalePreferenceConfiguration)this.languageSettings.get(), AdminappLanguageSettingsData.class);
      return Response.ok().entity(data).build();
   }

   @ApiResponse(
      description = "Retrieved custom URLs.",
      responseCode = "200",
      content = @Content(mediaType = "application/json", schema = @Schema(implementation = CustomUrlData.class))
   )
   @Path("/custom-urls")
   @GET
   @Operation(extensions = @Extension(properties = @ExtensionProperty(name = "x-internal", value = "true")))
   @Consumes("application/json")
   @Produces("application/json")
   public Response retrieveCustomUrls() {
      CustomUrlData data = (CustomUrlData)((MapperFacade)this.mapper.get()).map((AdminappCustomUrlSettings)this.customUrlSettings.get(), CustomUrlData.class);
      return Response.ok().entity(data).build();
   }

   @ApiResponse(
      description = "Retrieved dynamic URL validation result.",
      responseCode = "200",
      content = @Content(mediaType = "application/json", schema = @Schema(implementation = DynamicUrlValidation.class))
   )
   @POST
   @Operation(extensions = @Extension(properties = @ExtensionProperty(name = "x-internal", value = "true")))
   @Consumes("application/json")
   @Produces("application/json")
   @Path("/validate-dynamic-urls")
   public Response validateDynamicUrls(@NotNull @Valid UrlValidationRequest request) {
      DynamicUrlValidation dynamicUrlValidation = DynamicUrlValidation.builder()
         .matchesAllowedAfterLogoutUrlPattern(((RedirectSettings)this.redirectSettings.get()).isValidAfterLogoutUrl(request.getAfterLogoutUrl()))
         .matchesAllowedLoginUrlPattern(((RedirectSettings)this.redirectSettings.get()).isValidLoginUrl(request.getLoginUrl()))
         .build();
      return Response.ok(dynamicUrlValidation).build();
   }
}
