package com.airlock.iam.transactionapproval.infrastructure.resource.identification;

import com.airlock.iam.flow.infrastructure.mapper.ValidationResultMapper;
import com.airlock.iam.flow.shared.application.service.identification.UserIdentification;
import com.airlock.iam.transactionapproval.api.infrastructure.generated.transfer.response.TransactionApprovalFlowResultDataResourceDocument;
import com.airlock.iam.transactionapproval.infrastructure.transfer.request.TransactionApprovalUsernameCheckRequest;
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.ws.rs.Consumes;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;

@Path("/transaction-approval/user")
public class UserIdentificationFlowResource {
   private final Provider<ValidationResultMapper> mapper;
   private final Provider<UserIdentification> userIdentification;

   @Inject
   public UserIdentificationFlowResource(Provider<UserIdentification> identification, Provider<ValidationResultMapper> mapper) {
      this.userIdentification = identification;
      this.mapper = mapper;
   }

   @ApiResponses(
      {
            @ApiResponse(
               responseCode = "200",
               description = "Transaction approval successful or further steps required.\n<br>Possible next step: <tt>PARAMETERS_REQUIRED</tt> (as documented <a href=\"#nextApprovalStepCodes\">here</a>).\n",
               content = {
                     @Content(
                        mediaType = "application/vnd.api+json",
                        schema = @Schema(implementation = TransactionApprovalFlowResultDataResourceDocument.class)
                     ),
                     @Content(mediaType = "application/json", schema = @Schema(implementation = TransactionApprovalFlowResultDataResourceDocument.class))
               }
            ),
            @ApiResponse(
               responseCode = "400",
               description = "<div class=\"iam-error-code\"><table>\n<tr>\n<td>USER_NOT_FOUND</td>\n<td>The user does not exist.</td>\n</tr>\n</table>\n</div>\n<br>Possible next step: <tt>USERNAME_REQUIRED</tt>.\n",
               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 current transaction approval flow has been aborted.",
               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
   @Path("/identify")
   @Consumes("application/json")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   @Operation(
      description = "Identifies the transmitted username.\n<div class=\"iam-resource-return\">Whether the username check was successful. If the attribute <tt>nextStep</tt> is present in the response,\n further steps are required to successfully approve the transaction. If the attribute is missing, transaction approval\n of the user was successful.</div>",
      tags = "User",
      summary = "Identify user"
   )
   public Response checkUsername(@Parameter(description = "Contains the username.") @Valid TransactionApprovalUsernameCheckRequest request) {
      return ((ValidationResultMapper)this.mapper.get())
         .toValidationResponse(((UserIdentification)this.userIdentification.get()).identifyUser(request.getUsername(), null));
   }
}
