package com.oguerreiro.resilient.service.dto;

import java.util.HashSet;
import java.util.Set;

import com.oguerreiro.resilient.domain.enumeration.InputMode;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;

/**
 * A DTO for the {@link com.oguerreiro.resilient.domain.Variable} entity.
 */
@Schema(description = "Variable Definition (GEE variable classification)")
public class VariableDTO extends AbstractResilientDTO<Long> {
  private static final long serialVersionUID = 1L;

  @NotNull
  @Pattern(regexp = "^[0-9]*$")
  @Schema(description = "Unique key, composed by: <br>\nVariableScope.code + VariableCategory.code + <index>\nNOTA: User will provide the index property, and the software will create the code\nindex and code are NOT changeable", requiredMode = Schema.RequiredMode.REQUIRED)
  private String code;

  @Schema(description = "Variable index", requiredMode = Schema.RequiredMode.REQUIRED)
  private Integer variableIndex;

  @NotNull
  @Schema(description = "The name or title for the variable", requiredMode = Schema.RequiredMode.REQUIRED)
  private String name;

  @NotNull
  @Schema(description = "The descriptions of the variable. Its meaning. Its usage.", requiredMode = Schema.RequiredMode.REQUIRED)
  private String description;

  @NotNull
  @Schema(description = "Defines this variable as input. Values will be inserted for this variable", requiredMode = Schema.RequiredMode.REQUIRED)
  private Boolean input;

  @Schema(description = "Defines the way of input. See the enum for instructions.", requiredMode = Schema.RequiredMode.REQUIRED)
  private InputMode inputMode;

  @NotNull
  @Schema(description = "Defines this variable as output. This variable will be evaluated for output", requiredMode = Schema.RequiredMode.REQUIRED)
  private Boolean output;

  private Boolean outputSingle;

  private OrganizationDTO outputOwner;

  @Schema(description = "The formula to calculate the output valut of the variable. Mandatory when output==TRUE")
  private String outputFormula;

  @Schema(description = "The scale to use to round the value")
  private Integer valueScale;

  @NotNull
  @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
  private UnitDTO baseUnit;

  private VariableScopeDTO variableScope;
  private VariableCategoryDTO variableCategory;
  private VariableClassTypeDTO variableClassType;

  private String variableClassLabel;
  private Boolean variableClassMandatory;
  private Boolean hiddenForMain;

  private Set<VariableUnitsDTO> variableUnits = new HashSet<>();

  public String getCode() {
    return code;
  }

  public void setCode(String code) {
    this.code = code;
  }

  public Integer getVariableIndex() {
    return variableIndex;
  }

  public void setVariableIndex(Integer variableIndex) {
    this.variableIndex = variableIndex;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public Boolean getInput() {
    return input;
  }

  public void setInput(Boolean input) {
    this.input = input;
  }

  public InputMode getInputMode() {
    return inputMode;
  }

  public void setInputMode(InputMode inputMode) {
    this.inputMode = inputMode;
  }

  public Boolean getOutput() {
    return output;
  }

  public void setOutput(Boolean output) {
    this.output = output;
  }

  public String getOutputFormula() {
    return outputFormula;
  }

  public void setOutputFormula(String outputFormula) {
    this.outputFormula = outputFormula;
  }

  public Integer getValueScale() {
    return valueScale;
  }

  public void setValueScale(Integer valueScale) {
    this.valueScale = valueScale;
  }

  public UnitDTO getBaseUnit() {
    return baseUnit;
  }

  public void setBaseUnit(UnitDTO baseUnit) {
    this.baseUnit = baseUnit;
  }

  public VariableScopeDTO getVariableScope() {
    return variableScope;
  }

  public void setVariableScope(VariableScopeDTO variableScope) {
    this.variableScope = variableScope;
  }

  public VariableCategoryDTO getVariableCategory() {
    return variableCategory;
  }

  public void setVariableCategory(VariableCategoryDTO variableCategory) {
    this.variableCategory = variableCategory;
  }

  public VariableClassTypeDTO getVariableClassType() {
    return variableClassType;
  }

  public void setVariableClassType(VariableClassTypeDTO variableClassType) {
    this.variableClassType = variableClassType;
  }

  public Set<VariableUnitsDTO> getVariableUnits() {
    return variableUnits;
  }

  public void setVariableUnits(Set<VariableUnitsDTO> variableUnits) {
    this.variableUnits = variableUnits;
  }

  public String getVariableClassLabel() {
    return variableClassLabel;
  }

  public void setVariableClassLabel(String variableClassLabel) {
    this.variableClassLabel = variableClassLabel;
  }

  public Boolean getVariableClassMandatory() {
    return variableClassMandatory;
  }

  public void setVariableClassMandatory(Boolean variableClassMandatory) {
    this.variableClassMandatory = variableClassMandatory;
  }

  public Boolean getHiddenForMain() {
    return hiddenForMain;
  }

  public void setHiddenForMain(Boolean hiddenForMain) {
    this.hiddenForMain = hiddenForMain;
  }

  public Boolean getOutputSingle() {
    return outputSingle;
  }

  public void setOutputSingle(Boolean outputSingle) {
    this.outputSingle = outputSingle;
  }

  public OrganizationDTO getOutputOwner() {
    return outputOwner;
  }

  public void setOutputOwner(OrganizationDTO outputOwner) {
    this.outputOwner = outputOwner;
  }

  //@formatter:off
  @Override
  public String toString() {
    return "VariableDTO{" + 
              "id=" + getId() + 
              ", code='" + getCode() + "'" + 
              ", variableIndex=" + getVariableIndex() + 
              ", name='" + getName() + "'" + 
              ", description='" + getDescription() + "'" + 
              ", input='" + getInput() + "'" + 
              ", inputMode='" + getInputMode() + "'" + 
              ", output='" + getOutput() + "'" + 
              ", outputFormula='" + getOutputFormula() + "'" + 
              ", valueScale=" + getValueScale() + 
              ", baseUnit=" + getBaseUnit() + 
              ", variableScope=" + getVariableScope() + 
              ", variableCategory=" + getVariableCategory() + 
              ", variableClasstype=" + getVariableClassType() + 
              ", variableUnits=" + getVariableUnits() +
              ", hiddenForMain=" + getHiddenForMain() +
              ", version=" + getVersion() + 
           "}";
  }
  //@formatter:on
}
