package ru.micord.ervu.dto;

import java.util.ArrayList;
import java.util.List;

import static org.springframework.util.StringUtils.hasText;
import static ru.micord.ervu.util.DateUtil.convertToLocalDate;
import static ru.micord.ervu.util.DateUtil.convertToString;

/**
 * @author gulnaz
 */
public record SubpoenaResponseDto(String personName, String birthDate, String docType, String docNumber,
                                  String issueDate, String issueOrg, String issueIdCode,
                                  String residenceAddress, String actualAddress, String stayAddress,
                                  String seriesAndNumber, String visitDateTime,
                                  String militaryCommissariatName, String militaryCommissariatAddress,
                                  String militaryCommissar, String placementDateSummons, String reasonName,
                                  String summonsStatusName, String deliveryTypeSummonsName,
                                  String estimatedDateSummons, List<Restriction> restrictions,
                                  String firstRestrictionName, String firstRestrictionStartDate,
                                  int otherRestrictionCount, int recruitmentStatusCode,
                                  String recruitmentStartDate, int daysToAppearance) {

  public static final class Builder {
    String personName;
    String birthDate;
    String docType;
    String docNumber;
    String issueDate;
    String issueOrg;
    String issueIdCode;
    String residenceAddress;
    String actualAddress;
    String stayAddress;
    String seriesAndNumber;
    String visitDateTime;
    String militaryCommissariatName;
    String militaryCommissariatAddress;
    String militaryCommissar;
    String placementDateSummons;
    String reasonName;
    String summonsStatusName;
    String deliveryTypeSummonsName;
    String estimatedDateSummons;
    List<Restriction> restrictions;
    String firstRestrictionName;
    String firstRestrictionStartDate;
    int otherRestrictionCount;
    int recruitmentStatusCode;
    String recruitmentStartDate;
    int daysToAppearance;

    public Builder() {
      this.restrictions = new ArrayList<>();
    }

    public Builder personName(String firstName, String middleName, String lastName) {
      StringBuilder stringBuilder = new StringBuilder(lastName)
          .append(" ")
          .append(firstName);

      if (hasText(middleName)) {
        stringBuilder.append(" ")
            .append(middleName);
      }
      this.personName = stringBuilder.toString();
      return this;
    }

    public Builder birthDate(String birthDate) {
      this.birthDate = birthDate;
      return this;
    }

    public Builder docType(String docType) {
      this.docNumber = docType;
      return this;
    }

    public Builder docNumber(String series, String number) {
      this.docNumber = hasText(series) ? series + " " + number : number;
      return this;
    }

    public Builder issueDate(String issueDate) {
      this.issueDate = issueDate;
      return this;
    }

    public Builder issueOrg(String issueOrg) {
      this.issueOrg = issueOrg;
      return this;
    }

    public Builder issueIdCode(String issueIdCode) {
      this.issueIdCode = issueIdCode;
      return this;
    }

    public Builder residenceAddress(String residenceAddress) {
      this.residenceAddress = residenceAddress;
      return this;
    }

    public Builder actualAddress(String actualAddress) {
      this.actualAddress = actualAddress;
      return this;
    }

    public Builder stayAddress(String stayAddress) {
      this.stayAddress = stayAddress;
      return this;
    }

    public Builder seriesAndNumber(String series, String number) {
      this.seriesAndNumber = series + " " + number;
      return this;
    }

    public Builder visitDateTime(String date, String time) {
      this.visitDateTime = convertToString(convertToLocalDate(date)) + " в " + time;
      return this;
    }

    public Builder militaryCommissariatName(String militaryCommissariatName) {
      this.militaryCommissariatName = militaryCommissariatName;
      return this;
    }

    public Builder militaryCommissariatAddress(String militaryCommissariatAddress) {
      this.militaryCommissariatAddress = militaryCommissariatAddress;
      return this;
    }

    public Builder militaryCommissar(String militaryComissar, String militaryComissarFirstName,
                                    String militaryComissarMiddleName) {
      this.militaryCommissar = militaryComissar + " " + militaryComissarFirstName + " "
                               + militaryComissarMiddleName;
      return this;
    }

    public Builder placementDateSummons(String placementDateSummons) {
      this.placementDateSummons = placementDateSummons;
      return this;
    }

    public Builder reasonName(String reasonName) {
      this.reasonName = reasonName;
      return this;
    }

    public Builder summonsStatusName(String summonsStatusName) {
      this.summonsStatusName = summonsStatusName;
      return this;
    }

    public Builder deliveryTypeSummonsName(String deliveryTypeSummonsName) {
      this.deliveryTypeSummonsName = deliveryTypeSummonsName;
      return this;
    }

    public Builder estimatedDateSummons(String estimatedDateSummons) {
      this.estimatedDateSummons = estimatedDateSummons;
      return this;
    }

    public void addRestrictions(List<Restriction> restrictions) {
      this.restrictions.addAll(restrictions);
    }

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

    public void firstRestrictionStartDate(String date) {
      this.firstRestrictionStartDate = date;
    }

    public Builder otherRestrictionCount(int count) {
      this.otherRestrictionCount = count;
      return this;
    }

    public Builder recruitmentStatusCode(int recruitmentStatusCode) {
      this.recruitmentStatusCode = recruitmentStatusCode;
      return this;
    }

    public Builder recruitmentStartDate(String recruitmentStartDate) {
      this.recruitmentStartDate = recruitmentStartDate;
      return this;
    }

    public Builder daysToAppearance(int days) {
      this.daysToAppearance = days;
      return this;
    }

    public SubpoenaResponseDto build() {
      return new SubpoenaResponseDto(personName, birthDate, docType, docNumber, issueDate, issueOrg,
          issueIdCode, residenceAddress, actualAddress, stayAddress, seriesAndNumber, visitDateTime,
          militaryCommissariatName, militaryCommissariatAddress, militaryCommissar,
          placementDateSummons, reasonName, summonsStatusName, deliveryTypeSummonsName,
          estimatedDateSummons, restrictions, firstRestrictionName, firstRestrictionStartDate,
          otherRestrictionCount, recruitmentStatusCode, recruitmentStartDate, daysToAppearance);
    }
  }
}
