package io.delphiplatform.api.v3.model.gras;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import org.openapitools.jackson.nullable.JsonNullable;

import java.time.LocalDate;
import java.util.Objects;

import javax.validation.constraints.NotNull;

import io.delphiplatform.api.v3.rdb.entity.ProjectEntity;
import io.delphiplatform.api.v3.rdb.entity.ProjectTypeEntity;

@JsonPropertyOrder(alphabetic = true)
public class Project {

    @JsonProperty("project_id")
    private String projectId;

    @JsonProperty("raas_init_date")
    private JsonNullable<LocalDate> raasInitDate = JsonNullable.undefined();

    @JsonProperty("project_number")
    private String projectNumber;

    @JsonProperty("project_title")
    private String projectTitle;

    @JsonProperty("project_type")
    private String projectType;

    @JsonProperty("project_type_name")
    private String projectTypeName;

    @JsonProperty("raas_init_key")
    private String raasInitKey;

    @JsonProperty("rep_owner_key")
    private String repOwnerKey;

    @JsonProperty("rep_owner_company")
    private Company repOwnerCompany;

    @JsonProperty("label_id")
    private String labelId;

    @JsonProperty("label_name")
    private String labelName;

    public static Project from(ProjectEntity entity) {
        if (entity == null) {
            return null;
        }

        ProjectTypeEntity projectType = entity.getRecProjectType();
        return new Project()
            .projectId(entity.getProjectId())
            .raasInitDate(entity.getRaasInitDate())
            .projectNumber(entity.getRecProjectNumber())
            .projectTitle(entity.getRecProjectTitle())
            .projectType(projectType == null ? null : String.valueOf(projectType.getRecProjectType()))
            .projectTypeName(projectType == null ? null : projectType.getRecProjectTypeName())
            .raasInitKey(entity.getRaasInitCompany() == null ? null : entity.getRaasInitCompany().getCompanyKey())
            .repOwnerKey(entity.getRepertoireOwner() == null ? null : entity.getRepertoireOwner().getRepOwnerKey())
            .repOwnerCompany(entity.getRepertoireOwner() == null
                ? null : Company.from(entity.getRepertoireOwner().getRepertoireOwnerCompany()))
            .labelId(entity.getLabel() == null ? null : entity.getLabel().getLabelId())
            .labelName(entity.getLabel() == null ? null : entity.getLabel().getName());
    }

    public Project projectId(String projectId) {
        this.projectId = projectId;
        return this;
    }

    /**
     * Primary key identifier for a Project.
     *
     * @return projectId
     */
    @NotNull
    public String getProjectId() {
        return projectId;
    }

    public void setProjectId(String projectId) {
        this.projectId = projectId;
    }

    public Project raasInitDate(LocalDate raasInitDate) {
        this.raasInitDate = JsonNullable.of(raasInitDate);
        return this;
    }

    /**
     * ISO 8601 date in format `YYYY-MM-DD`
     *
     * @return raasInitDate
     */
    @NotNull
    public JsonNullable<LocalDate> getRaasInitDate() {
        return raasInitDate;
    }

    public void setRaasInitDate(JsonNullable<LocalDate> raasInitDate) {
        this.raasInitDate = raasInitDate;
    }

    public Project projectNumber(String projectNumber) {
        this.projectNumber = projectNumber;
        return this;
    }

    /**
     * Project number of the Project.
     *
     * @return projectNumber
     */
    @NotNull
    public String getProjectNumber() {
        return projectNumber;
    }

    public void setProjectNumber(String projectNumber) {
        this.projectNumber = projectNumber;
    }

    public Project projectTitle(String projectTitle) {
        this.projectTitle = projectTitle;
        return this;
    }

    /**
     * Project title of the Project.
     *
     * @return projectTitle
     */
    @NotNull
    public String getProjectTitle() {
        return projectTitle;
    }

    public void setProjectTitle(String projectTitle) {
        this.projectTitle = projectTitle;
    }

    public Project projectType(String projectType) {
        this.projectType = projectType;
        return this;
    }

    /**
     * Project type of the Project.
     *
     * @return projectType
     */
    @NotNull
    public String getProjectType() {
        return projectType;
    }

    public void setProjectType(String projectType) {
        this.projectType = projectType;
    }

    public Project projectTypeName(String projectTypeName) {
        this.projectTypeName = projectTypeName;
        return this;
    }

    /**
     * Project type name of the Project.
     *
     * @return projectTypeName
     */
    @NotNull
    public String getProjectTypeName() {
        return projectTypeName;
    }

    public void setProjectTypeName(String projectTypeName) {
        this.projectTypeName = projectTypeName;
    }

    public Project raasInitKey(String raasInitKey) {
        this.raasInitKey = raasInitKey;
        return this;
    }

    /**
     * Primary key identifier for a Company, also used via RepertoireOwner, ParentRepertoireOwner and ProfitCenter.
     *
     * @return raasInitKey
     */
    @NotNull
    public String getRaasInitKey() {
        return raasInitKey;
    }

    public void setRaasInitKey(String raasInitKey) {
        this.raasInitKey = raasInitKey;
    }

    public Project repOwnerKey(String repOwnerKey) {
        this.repOwnerKey = repOwnerKey;
        return this;
    }

    /**
     * Primary key identifier for a Company, also used via RepertoireOwner, ParentRepertoireOwner and ProfitCenter.
     *
     * @return repOwnerKey
     */
    @NotNull
    public String getRepOwnerKey() {
        return repOwnerKey;
    }

    public void setRepOwnerKey(String repOwnerKey) {
        this.repOwnerKey = repOwnerKey;
    }

    public Project labelId(String labelId) {
        this.labelId = labelId;
        return this;
    }

    public Project repOwnerCompany(Company repOwnerCompany) {
        this.repOwnerCompany = repOwnerCompany;
        return this;
    }

    public Company getRepOwnerCompany() {
        return repOwnerCompany;
    }

    public void setRepOwnerCompany(Company repOwnerCompany) {
        this.repOwnerCompany = repOwnerCompany;
    }

    /**
     * Primary key identifier for a Label
     *
     * @return labelId
     */
    @NotNull
    public String getLabelId() {
        return labelId;
    }

    public void setLabelId(String labelId) {
        this.labelId = labelId;
    }

    public Project labelName(String labelName) {
        this.labelName = labelName;
        return this;
    }

    /**
     * Name of the label
     *
     * @return labelName
     */
    public String getLabelName() {
        return labelName;
    }

    public void setLabelName(String labelName) {
        this.labelName = labelName;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Project project = (Project) o;
        return Objects.equals(this.projectId, project.projectId) &&
            Objects.equals(this.raasInitDate, project.raasInitDate) &&
            Objects.equals(this.projectNumber, project.projectNumber) &&
            Objects.equals(this.projectTitle, project.projectTitle) &&
            Objects.equals(this.projectType, project.projectType) &&
            Objects.equals(this.projectTypeName, project.projectTypeName) &&
            Objects.equals(this.raasInitKey, project.raasInitKey) &&
            Objects.equals(this.repOwnerKey, project.repOwnerKey) &&
            Objects.equals(this.repOwnerCompany, project.repOwnerCompany) &&
            Objects.equals(this.labelId, project.labelId);
    }

    @Override
    public int hashCode() {
        return Objects
            .hash(projectId, raasInitDate, projectNumber, projectTitle, projectType, projectTypeName, raasInitKey,
                repOwnerKey, labelId);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class Project {\n");

        sb.append("    projectId: ").append(toIndentedString(projectId)).append("\n");
        sb.append("    raasInitDate: ").append(toIndentedString(raasInitDate)).append("\n");
        sb.append("    projectNumber: ").append(toIndentedString(projectNumber)).append("\n");
        sb.append("    projectTitle: ").append(toIndentedString(projectTitle)).append("\n");
        sb.append("    projectType: ").append(toIndentedString(projectType)).append("\n");
        sb.append("    projectTypeName: ").append(toIndentedString(projectTypeName)).append("\n");
        sb.append("    raasInitKey: ").append(toIndentedString(raasInitKey)).append("\n");
        sb.append("    repOwnerKey: ").append(toIndentedString(repOwnerKey)).append("\n");
        sb.append("    repOwnerCompany: ").append(toIndentedString(repOwnerCompany)).append("\n");
        sb.append("    labelId: ").append(toIndentedString(labelId)).append("\n");
        sb.append("    labelName: ").append(toIndentedString(labelName)).append("\n");
        sb.append("}");
        return sb.toString();
    }

    /**
     * Convert the given object to string with each line indented by 4 spaces (except the first line).
     */
    private String toIndentedString(Object o) {
        if (o == null) {
            return "null";
        }
        return o.toString().replace("\n", "\n    ");
    }
}

