package com.airlock.iam.admin.infrastructure.resource.prot.user;

import com.airlock.iam.admin.application.service.user.UserValidityService;
import com.airlock.iam.admin.domain.model.user.UserSpecificSettings;
import com.airlock.iam.admin.infrastructure.service.user.UserIdResolver;
import com.airlock.iam.admin.infrastructure.transfer.request.user.UserValidityUntilRequest;
import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.log.api.helpdesk.HelpdeskLogger;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
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 io.swagger.v3.oas.annotations.responses.ApiResponses;
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.DELETE;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;

@Path("/users/{userId}/validity/until")
public class UserValidityUntilResource {
   private final Provider<UserValidityService> validityService;
   private final Provider<UserSpecificSettings> settings;
   private final HelpdeskLogger helpdeskLogger;
   private final Provider<UserIdResolver> userIdResolver;

   @Inject
   public UserValidityUntilResource(
      Provider<UserValidityService> userValidityServiceProvider,
      Provider<UserSpecificSettings> settings,
      HelpdeskLogger logger,
      Provider<UserIdResolver> userIdResolver
   ) {
      this.validityService = userValidityServiceProvider;
      this.settings = settings;
      this.helpdeskLogger = logger;
      this.userIdResolver = userIdResolver;
   }

   @ApiResponses(
      {
            @ApiResponse(responseCode = "204", description = "The user's validity period 'until' date has been created."),
            @ApiResponse(
               responseCode = "400",
               description = "The request was invalid.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            ),
            @ApiResponse(
               responseCode = "403",
               description = "The user is not editable.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            ),
            @ApiResponse(
               responseCode = "404",
               description = "The user does not exist.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            )
      }
   )
   @POST
   @Consumes("application/json")
   @Operation(
      description = "Sets the 'until' date of a user validity period.\n<div class=\"iam-resource-return\">a bean delivering the outcome of the operation to the client.</div>",
      tags = "User Validity",
      summary = "Set until date"
   )
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response setValidUntil(
      @PathParam("userId") @Parameter(schema = @Schema(type = "string")) String userIdParam,
      @Parameter(description = "Contains the date until the user will be valid.") @NotNull @Valid UserValidityUntilRequest request
   ) {
      UserId userId = ((UserIdResolver)this.userIdResolver.get()).resolve(userIdParam);
      ((UserSpecificSettings)this.settings.get()).failIfUserNotEditable();
      ((UserValidityService)this.validityService.get()).setValidUntil(userId.getValue(), request.getUntil());
      this.helpdeskLogger.log(userId, "Administrator ${authentee} set that user ${affectedUser} is valid until %tF.", new Object[]{request.getUntil()});
      return Response.noContent().build();
   }

   @ApiResponses(
      {
            @ApiResponse(responseCode = "204", description = "The user's validity period 'until' date has been deleted."),
            @ApiResponse(
               responseCode = "403",
               description = "The user is not editable.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            ),
            @ApiResponse(
               responseCode = "404",
               description = "The user does not exist.",
               content = {
                     @Content(mediaType = "application/vnd.api+json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse")),
                     @Content(mediaType = "application/json", schema = @Schema(ref = "json-api.yaml#/components/schemas/ErrorDocumentResponse"))
               }
            )
      }
   )
   @DELETE
   @Operation(
      description = "Deletes the 'until' date of a user validity period.\n<div class=\"iam-resource-return\">a bean delivering the outcome of the operation to the client.</div>",
      tags = "User Validity",
      summary = "Delete until date"
   )
   @Consumes("application/json")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response resetValidUntil(@PathParam("userId") @Parameter(schema = @Schema(type = "string")) String userIdParam) {
      UserId userId = ((UserIdResolver)this.userIdResolver.get()).resolve(userIdParam);
      ((UserSpecificSettings)this.settings.get()).failIfUserNotEditable();
      ((UserValidityService)this.validityService.get()).resetValidUntil(userId.getValue());
      this.helpdeskLogger.log(userId, "Administrator ${authentee} reset the date until user ${affectedUser} is valid.");
      return Response.noContent().build();
   }
}
