package gov.cms.grouper.snf.model.table;

import gov.cms.grouper.snf.lego.CsvBuilder;
import gov.cms.grouper.snf.lego.SnfUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.function.BiConsumer;

public class NtaComorbidityRow extends BasicRow {
  private String conditionService;
  private SortedSet<String> mdsItems;
  private Integer point;

  private NtaComorbidityRow() {
    this(null, null, null);
  }

  public NtaComorbidityRow(String conditionService, SortedSet<String> mdsItems, Integer point) {
    this.conditionService = conditionService;
    this.mdsItems = mdsItems;
    this.point = point;
  }

  public String getConditionService() {
    return this.conditionService;
  }

  public SortedSet<String> getMdsItems() {
    return this.mdsItems;
  }

  public Integer getPoint() {
    return this.point;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = super.getHashCode(result, prime);
    result =
        prime * result + ((this.conditionService == null) ? 0 : this.conditionService.hashCode());
    result = prime * result + ((this.mdsItems == null) ? 0 : this.mdsItems.hashCode());
    result = prime * result + ((this.point == null) ? 0 : this.point.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (this.getClass() != obj.getClass()) {
      return false;
    }
    NtaComorbidityRow other = (NtaComorbidityRow) obj;
    if (super.equals(other) == false) {
      return false;
    }

    if (this.conditionService == null) {
      if (other.conditionService != null) {
        return false;
      }
    } else if (!this.conditionService.equals(other.conditionService)) {
      return false;
    }
    if (this.mdsItems == null) {
      if (other.mdsItems != null) {
        return false;
      }
    } else if (!this.mdsItems.equals(other.mdsItems)) {
      return false;
    }
    if (this.point == null) {
      if (other.point != null) {
        return false;
      }
    } else if (!this.point.equals(other.point)) {
      return false;
    }
    return true;
  }

  public static class Builder extends CsvBuilder<NtaComorbidityRow> {
    private static final BiConsumer<NtaComorbidityRow, String> conditionService =
        (rowModel, value) -> rowModel.conditionService = SnfUtils.clean(value);

    private static final BiConsumer<NtaComorbidityRow, String> mdsItem =
        (rowModel, value) -> rowModel.mdsItems =
            SnfUtils.nullCheck2(SnfUtils.clean(value), () -> SnfUtils.toOrderedSet(""), () -> {
              SortedSet<String> codes = SnfUtils.toOrderedSet(SnfUtils.clean(value).split("\\|"));
              return codes;
            });

    private static final BiConsumer<NtaComorbidityRow, String> point =
        (rowModel, value) -> rowModel.point = SnfUtils.parse(value, null);

    private Builder() {
      super(NtaComorbidityRow::new, Builder.initCsvMapping());
    }

    private static Map<Integer, BiConsumer<NtaComorbidityRow, String>> initCsvMapping() {
      Map<Integer, BiConsumer<NtaComorbidityRow, String>> result = new HashMap<>();
      result.put(0, Builder.conditionService);
      result.put(1, BasicRow.getLowVersionParser());
      result.put(2, BasicRow.getHighVersionParser());
      result.put(3, Builder.mdsItem);
      result.put(4, Builder.point);

      return Collections.unmodifiableMap(result);
    }

    private static final Builder singleton = new Builder();

    public static Builder of() {
      return Builder.singleton;
    }
  }

}
