package com.airlock.iam.flow.shared.infrastructure.mapper;

import ch.ergon.restal.jsonapi.document.error.ErrorData;
import com.airlock.iam.base.api.domain.model.validation.ValidationResult;
import com.airlock.iam.base.infrastructure.mapper.ErrorCodeMapper;
import com.airlock.iam.base.infrastructure.mapper.StaticErrorCodeMapper;
import com.airlock.iam.base.infrastructure.mapper.ValidationToErrorMapper;
import com.airlock.iam.flow.api.domain.model.flow.FlowResult;
import com.airlock.iam.flow.api.domain.model.step.StepError;
import com.airlock.iam.flow.api.infrastructure.mapper.FlowResultMapper;
import com.airlock.iam.flow.domain.model.ValidationStepResultData;
import com.airlock.iam.flow.infrastructure.mapper.ValidationResultMapper;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.ws.rs.core.Response;
import java.util.List;

public class ValidationResultMapperImpl implements ValidationResultMapper {
   private final Provider<ValidationToErrorMapper> errorMapper;
   private final Provider<FlowResultMapper> flowResultMapper;

   @Inject
   public ValidationResultMapperImpl(Provider<ValidationToErrorMapper> errorMapper, Provider<FlowResultMapper> flowResultMapper) {
      this.errorMapper = errorMapper;
      this.flowResultMapper = flowResultMapper;
   }

   @Override
   public List<ErrorData> toErrorData(StepError stepError, ValidationResult validationResult) {
      return this.toErrorData(StaticErrorCodeMapper.of(stepError::name), validationResult);
   }

   @Override
   public List<ErrorData> toErrorData(ErrorCodeMapper errorCodeMapper, ValidationResult validationResult) {
      return ((ValidationToErrorMapper)this.errorMapper.get()).withErrorCodeMapper(errorCodeMapper).toErrorData(validationResult.getErrors());
   }

   @Override
   public Response toValidationResponse(FlowResult result) {
      ValidationResult validationResult = result.data(ValidationStepResultData.class).map(ValidationStepResultData::result).orElse(ValidationResult.valid());
      if (!validationResult.isValid()) {
         List<ErrorData> errors = this.toErrorData(result.error().get(), validationResult);
         return ((FlowResultMapper)this.flowResultMapper.get()).toResponse(result, errors);
      } else {
         return ((FlowResultMapper)this.flowResultMapper.get()).toResponse(result);
      }
   }
}
