package ru.nbch.credit_tracker.builder;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import ru.nbch.credit_tracker.entities.external_request.signals.Person;
import ru.nbch.credit_tracker.service.indic.PersonService;
import ru.nbch.credit_tracker.utils.CTUtil;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;

@Slf4j
public class PersonFactoryBuilder {
    private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy");

    private final static String DEFAULT_DATE = "01.01.2000";
    private final static String IP = "0";
    private final static String OKSM = "999";
    private final static String CONSENT_PURPOSE = "16";
    private final static String REPORT_USER = "АО «НБКИ»";
    private final static String LIABILITY = "1";
    private final static String CONSENT_PERIOD = "3";
    private final static String REPORT_USER_REG_NUM = "1057746710713";
    private final static String REPORT_USER_TAX_ID = "7703548386";
    private final static String CONSENT_HASH = "hash";
    private final static String CONSENT_DIV_CODE = "000-000";
    private final static String INQ_PURPOSE = "16";
    private final static String ODT = "Иной документ";
    private final static String CONSENT_ISSUE_AUTHORITY = "Кем выдан";


    private PersonService.PersonData personData;
    private Integer uid;

    public static PersonFactoryBuilder builder() {
        return new PersonFactoryBuilder();
    }

    public PersonFactoryBuilder personData(PersonService.PersonData personData) {
        this.personData = personData;
        return this;
    }

    public PersonFactoryBuilder uid(Integer uid) {
        this.uid = uid;
        return this;
    }

    public Person build() {
        if (personData == null) {
            return null;
        }
        PersonService.NameData nameData = personData.getName();
        PersonService.PassportData passportData = personData.getPassport();
        Person person = new Person();
        person.setS(nameData.getLastName());
        person.setN(nameData.getFirstName());
        person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null);
        person.setD(DATE_FORMAT.format(CTUtil.localDatetoDate(nameData.getBirthDate())));

        person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum()));
        person.setPd(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now()))); // Do not use passport iss_date. Signal service could reject the package
        person.setDt(getDt(passportData.getIdType(), passportData.getIdType2()));
        if (person.getDt() != null && person.getDt().equals("999")) {
            person.setOdt(ODT);
            person.setConsentOdt(ODT);
        }
        person.setIp(IP);
        person.setUid(uid);
        person.setOksm(OKSM);
        person.setConsentDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
        person.setConsentPurpose(CONSENT_PURPOSE);
        person.setReportUser(REPORT_USER);
        person.setLiability(LIABILITY);
        person.setConsentPeriod(CONSENT_PERIOD);
        person.setAgrDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
        person.setReportUserRegNum(REPORT_USER_REG_NUM);
        person.setReportUserTaxID(REPORT_USER_TAX_ID);
        person.setConsentHash(CONSENT_HASH);

        person.setCs(person.getS());
        person.setConsentN(person.getN());
        person.setConsentM(person.getM());
        person.setConsentBd(person.getD());
        person.setConsentPn(person.getPn());
        person.setConsentPd(person.getPd());
        person.setConsentDivCode(CONSENT_DIV_CODE);
        person.setConsentDt(person.getDt());
        person.setConsentIssueAuthority(CONSENT_ISSUE_AUTHORITY);
        person.setInqPurpose(INQ_PURPOSE);
        return person;
    }

    private String getPn(String serNum, String idNum) {
        String normSerNum = CTUtil.normalize(serNum);
        String normIdNum = CTUtil.normalize(idNum);
        return StringUtils.isNotBlank(normSerNum) ? normSerNum + normIdNum : normIdNum;
    }

    private String getDt(String idType, String idType2) {
        if (StringUtils.isNotBlank(idType2)) {
            return idType2;
        } else {
            return switch (idType) {
                case "21" -> "21";
                case "22" -> "22.1";
                case "09" -> "22.2";
                case "26" -> "23";
                case "04" -> "24";
                case "07" -> "25";
                case "14", "03" -> "27";
                case "10" -> "31";
                case "15" -> "32";
                case "13" -> "37";
                case "06", "27" -> "28";
                case "01", "02" -> "999";
                default -> {
                    log.warn("ID_TYPE2 is blank and no matching found for ID_TYPE {}", idType);
                    yield "";
                }
            };
        }
    }
}
