package com.airlock.iam.authentication.infrastructure.resource;

import com.airlock.iam.authentication.infrastructure.generated.transfer.response.CrontoPushActivationChallengeDataResourceDocument;
import com.airlock.iam.authentication.infrastructure.transfer.response.CrontoPushActivationChallengeData;
import com.airlock.iam.flow.api.domain.model.flow.FlowResult;
import com.airlock.iam.flow.api.infrastructure.mapper.FlowResultMapper;
import com.airlock.iam.flow.auth.api.infrastructure.generated.transfer.response.AuthenticationFlowResultDataResourceDocument;
import com.airlock.iam.flow.shared.domain.model.cronto.CrontoPushActivation;
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 jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Response;

@Path("/cronto/push-devices/activation")
public class CrontoPushActivationAuthenticationFlowResource {
   private final Provider<CrontoPushActivation> crontoActivation;
   private final FlowResultMapper mapper;

   @Inject
   public CrontoPushActivationAuthenticationFlowResource(Provider<CrontoPushActivation> crontoActivation, FlowResultMapper mapper) {
      this.crontoActivation = crontoActivation;
      this.mapper = mapper;
   }

   @ApiResponse(
      responseCode = "200",
      description = "Cronto push activation challenge created.\n<br>Next step: <tt>CRONTO_PUSH_ACTIVATION_POSSIBLE</tt> (as documented <a href=\"#nextAuthStepCodes\">here</a>).\n",
      content = {
            @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = CrontoPushActivationChallengeDataResourceDocument.class)),
            @Content(mediaType = "application/json", schema = @Schema(implementation = CrontoPushActivationChallengeDataResourceDocument.class))
      }
   )
   @Deprecated
   @Operation(
      description = "> [!caution]\n> This endpoint is deprecated. The challenge information is returned as\n<a href=\"#additionalAuthAttributes\">additional attribute</a> with the <tt>CRONTO_PUSH_ACTIVATION_POSSIBLE</tt> next step code.\n<p>Retrieves the Cronto push activation cryptogram.</p>\n<p>The retrieved Cronto activation challenge can be used to activate push notifications\nin the CrontoSign Swiss app.</p>\n<div class=\"iam-resource-return\">The Cronto push activation challenge.</div>",
      tags = "Cronto",
      summary = "Get cryptogram"
   )
   @POST
   @Path("/challenge/retrieve")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response retrievePushActivationChallenge() {
      FlowResult flowResult = ((CrontoPushActivation)this.crontoActivation.get()).retrievePushActivationChallenge();
      return this.mapper.toResponseWithData(flowResult, CrontoPushActivationChallengeData.class);
   }

   @ApiResponse(
      responseCode = "200",
      description = "Push activation skipped and authentication flow completed if no further steps required.",
      content = {
            @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class)),
            @Content(mediaType = "application/json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class))
      }
   )
   @Operation(
      description = "Skips the Cronto push activation.\nThe flow continues without push activation. After a configurable number of logins with this\ndevice, the push activation will be offered again.\n<div class=\"iam-resource-return\">A success result (skipping cannot fail).</div>",
      tags = "Cronto",
      summary = "Skip activation"
   )
   @POST
   @Path("/skip")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response skip() {
      return this.mapper.toResponse(((CrontoPushActivation)this.crontoActivation.get()).skip());
   }

   @ApiResponse(
      responseCode = "200",
      description = "Push activation skipped and push disabled on device. If no further steps are required, the authentication flow has completed.",
      content = {
            @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class)),
            @Content(mediaType = "application/json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class))
      }
   )
   @Operation(
      description = "Never activate push on this device.\nThe flow continues without push activation. The device is marked as not being push-enabled and\nthe user will never be asked again to activate push on this device.\n<div class=\"iam-resource-return\">A success result (selecting \"never\" cannot fail).</div>",
      tags = "Cronto",
      summary = "Never activate push"
   )
   @POST
   @Path("/never")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response never() {
      return this.mapper.toResponse(((CrontoPushActivation)this.crontoActivation.get()).never());
   }

   @ApiResponse(
      responseCode = "200",
      description = "Push not yet activated (retry later), authentication successful or further steps required.\n<br>Possible next steps: <tt>CRONTO_PUSH_ACTIVATION_POSSIBLE</tt> (as documented <a href=\"#nextAuthStepCodes\">here</a>).\n",
      content = {
            @Content(mediaType = "application/vnd.api+json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class)),
            @Content(mediaType = "application/json", schema = @Schema(implementation = AuthenticationFlowResultDataResourceDocument.class))
      }
   )
   @Operation(
      description = "Continues after Cronto push activation.\nVerifies that push activation was successful. This endpoint has \"polling\" semantic, as long as push activation\nis still pending, <tt>CRONTO_PUSH_ACTIVATION_POSSIBLE</tt> is returned. Once push activation is complete, the\nflow is continued.\n<div class=\"iam-resource-return\">A success result if the device successfully activated push.</div>",
      tags = "Cronto",
      summary = "Continue activation"
   )
   @POST
   @Path("/continue")
   @Produces({"application/vnd.api+json", "application/json;qs=0.9"})
   public Response checkCompleted(
      @Parameter(
   description = "Whether the final result should be returned (optional, default <tt>false</tt>). See <a href=\"#pollingEndpoints\">polling endpoints</a> for details."
) @QueryParam("queryOnly") boolean queryOnly
   ) {
      return this.mapper.toResponse(((CrontoPushActivation)this.crontoActivation.get()).checkCompleted(queryOnly));
   }
}
