package com.airlock.iam.admin.application.configuration.generic.ui;

import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.PropertyConfigurationException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(description = "Renders an input filed with a date picker for a date property.", displayName = "Date/Time Input Token Controller Element")
public final class DateInputTokenControllerUiElementConfig implements TokenControllerUiElementConfig {
   @StringProperty(
      description = "Label for the field. The UI treats it as a key to translate.\nIf there is no translation, the label is shown in the UI as is.",
      exampleValues = "userdata.label.birthdate",
      optional = false
   )
   private String label;
   @StringProperty(
      description = "The property to use as value for this field.\n<p>The referenced property must be available in the <code>attributes</code> value of the generic token REST call response.\nIf the property is nested, e.g. inside the <code>contextData</code> key, it can be referenced with dot notation (see example values).</p><p>The ID of the response is referenced by using the reserved value <code>@id</code>.</p>",
      optional = false,
      exampleValues = {"orderDate", "contextData.birthdate", "@id"}
   )
   private String property;
   @StringProperty(
      description = "Displays a placeholder when the field has no value.\nThe placeholder is not interpreted as value and disappears when typing in the field.",
      optional = true
   )
   private String placeholder;
   @BooleanProperty(
      description = "Whether this field must have a value when the token is added or updated.\nRequired fields are marked with an asterisk.",
      defaultValue = "false",
      optional = true
   )
   private boolean required;
   @BooleanProperty(
      description = "If enabled, the date is handled without time. The date picker changes accordingly.\nThe referenced property must be of a matching date type, e.g. a \"Date Context Data Item\".",
      displayName = "Date-only",
      defaultValue = "false",
      optional = true
   )
   private boolean dateOnly;
   @BooleanProperty(
      description = "If enabled, the field is read-only and cannot be altered by administrators via the UI.",
      displayName = "Read-only",
      defaultValue = "false",
      optional = true
   )
   private boolean readOnly;
   private static final String READ_ONLY_PROPERTY = "readOnly";
   @BooleanProperty(
      description = "If enabled, this UI element is hidden if it has no value.",
      displayName = "Hide If Empty",
      defaultValue = "false",
      optional = true
   )
   private boolean hideIfEmpty;
   private static final String HIDE_IF_EMPTY_PROPERTY = "hideIfEmpty";

   @ConfigurationValidator
   static void checkHideIfEmptyAllowed(PluginConfiguration pc, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment) throws PropertyConfigurationException {
      TokenControllerUiElementConfig.validateHideIfEmptyAllowed(pc, env, context, "readOnly", "hideIfEmpty");
   }

   public String getLabel() {
      return this.label;
   }

   public String getProperty() {
      return this.property;
   }

   public Optional<String> getPlaceholder() {
      return Optional.ofNullable(this.placeholder);
   }

   public boolean isRequired() {
      return this.required;
   }

   public boolean isDateOnly() {
      return this.dateOnly;
   }

   public boolean isReadOnly() {
      return this.readOnly;
   }

   public boolean isHideIfEmpty() {
      return this.hideIfEmpty;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder builder() {
      return new DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public DateInputTokenControllerUiElementConfig() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public DateInputTokenControllerUiElementConfig(
      String label, String property, String placeholder, boolean required, boolean dateOnly, boolean readOnly, boolean hideIfEmpty
   ) {
      this.label = label;
      this.property = property;
      this.placeholder = placeholder;
      this.required = required;
      this.dateOnly = dateOnly;
      this.readOnly = readOnly;
      this.hideIfEmpty = hideIfEmpty;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class DateInputTokenControllerUiElementConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String label;
      @SuppressFBWarnings(justification = "generated code")
      private String property;
      @SuppressFBWarnings(justification = "generated code")
      private String placeholder;
      @SuppressFBWarnings(justification = "generated code")
      private boolean required;
      @SuppressFBWarnings(justification = "generated code")
      private boolean dateOnly;
      @SuppressFBWarnings(justification = "generated code")
      private boolean readOnly;
      @SuppressFBWarnings(justification = "generated code")
      private boolean hideIfEmpty;

      @SuppressFBWarnings(justification = "generated code")
      DateInputTokenControllerUiElementConfigBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder label(String label) {
         this.label = label;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder property(String property) {
         this.property = property;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder placeholder(String placeholder) {
         this.placeholder = placeholder;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder required(boolean required) {
         this.required = required;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder dateOnly(boolean dateOnly) {
         this.dateOnly = dateOnly;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder readOnly(boolean readOnly) {
         this.readOnly = readOnly;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder hideIfEmpty(boolean hideIfEmpty) {
         this.hideIfEmpty = hideIfEmpty;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public DateInputTokenControllerUiElementConfig build() {
         return new DateInputTokenControllerUiElementConfig(
            this.label, this.property, this.placeholder, this.required, this.dateOnly, this.readOnly, this.hideIfEmpty
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "DateInputTokenControllerUiElementConfig.DateInputTokenControllerUiElementConfigBuilder(label="
            + this.label
            + ", property="
            + this.property
            + ", placeholder="
            + this.placeholder
            + ", required="
            + this.required
            + ", dateOnly="
            + this.dateOnly
            + ", readOnly="
            + this.readOnly
            + ", hideIfEmpty="
            + this.hideIfEmpty
            + ")";
      }
   }
}
