package cz.moneta.test.dsl.util.task.monetaportal.childbuildingsavings;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.szrmock.SzrMockData;
import cz.moneta.test.dsl.util.data.client.IdCard;
import cz.moneta.test.dsl.util.data.client.NewClientWithCurrentAccountInformation;
import cz.moneta.test.dsl.util.data.client.NonClient;
import cz.moneta.test.dsl.util.task.ib.IbLoginApiTasks;
import cz.moneta.test.harness.endpoints.ib.NewIbEndpoint;
import cz.moneta.test.harness.endpoints.udebs.UdebsEndpoint;
import cz.moneta.test.harness.support.auth.Credentials;
import org.jooq.Record;
import org.jooq.Result;
import org.junit.jupiter.api.Assertions;

import java.time.LocalDate;
import java.util.concurrent.TimeUnit;

import static cz.moneta.test.dsl.util.task.monetaportal.childbuildingsavings.ChildBuildingSavingsSQL.SQL_GET_USERID_AND_SESSION_ID;
import static cz.moneta.test.dsl.util.credentials.Keys.ufo.banka.banker;
import static cz.moneta.test.dsl.util.task.retail.loans.constants.DefaultLoansConstants.*;
import static cz.moneta.test.harness.support.auth.AuthSupport.getCredentials;

public class ChildBuildingSavingsUtils {
    private final Harness harness;

    public ChildBuildingSavingsUtils(Harness harness) {
        this.harness = harness;
    }

    public NonClient createClientFatherData() {
        return harness.data().newNonClient()
                .withEmail(DEFAULT_EMAIL)
                .withMobileNumber(DEFAULT_MOBILE_NUMBER)
                .withDriverLicenceId(DEFAULT_DRIVING_LICENSE_ID)
                .withDriveLicenceExpiryDateRaw(DEFAULT_DRIVING_LICENSE_EXPIRATION_DATE)
                .withResidencyAddress(DEFAULT_CLIENT_ADDRESS)
                .withIdCard(DEFAULT_ID_CARD);
    }

    public NonClient createClientMotherData(NonClient father) {
        return harness.data().newWomanNonClient()
                .withEmail(father.email())
                .withLastName(father.lastName())
                .withMobileNumber(father.mobileNumber())
                .withResidencyAddress(father.residencyAddress());
    }

    public NonClient createChildClientData(NonClient parent, int ageFrom, int ageTo) {
        return harness.data().newNonClient()
                .withBirthNumber(harness.tasks().common().getRcMinMaxAge(ageFrom, ageTo))
                .withEmail(parent.email())
                .withLastName(parent.lastName())
                .withMobileNumber(parent.mobileNumber())
                .withResidencyAddress(parent.residencyAddress())
                .withIdCard(new IdCard("209373728", LocalDate.of(2018, 8, 12), LocalDate.of(2028, 8, 12)));
    }

    public Credentials createClient(SzrMockData data) {
        String ufoUserName = getCredentials(banker, harness).getUsername();
        NewClientWithCurrentAccountInformation info = harness.dataPrepare().createNewFoCustomerWithCurrentAccountAndIbViaWso2(data.getClient(), ufoUserName);
        data.setCif(info.getCif());
        harness.tasks().szrMock().idAndPassE2E(data);
        harness.log(String.format("\n" +
                        "Name and Surname: %s %s\n" +
                        "Birth Number: %s\n" +
                        "Cif: %s"
                , data.getClient().firstName(), data.getClient().lastName(), data.getClient().birthNumber(), info.getCif()));
        Credentials cred = new IbLoginApiTasks(harness).loginAndConfirmAuthWithSms(info.getCredentials().getUsername());
        harness.log("\nUsername: " + cred.getUsername() + "\n" +
                "Password: " + cred.getPassword());
        return cred;
    }

    public String createChildExist(NonClient client) {
        String ufoUserName = getCredentials(banker, harness).getUsername();
        String cif = harness.dataPrepare().createNewFoCustomerViaWso2AndGetCif(client, ufoUserName);
        harness.log(String.format("\n" +
                        "Name and Surname: %s %s\n" +
                        "Birth Number: %s\n" +
                        "Cif: %s"
                , client.firstName(), client.lastName(), client.birthNumber(), cif));
        return cif;
    }

    public void storeUserIdAndSessionId(String cif) {
        Result<Record> resultUserID = harness.getEndpoint(UdebsEndpoint.class)
                .executeSql(SQL_GET_USERID_AND_SESSION_ID.replace("s%", cif));
        String userID = getValueFromResult(resultUserID, "USERID");
        String sessionId = getValueFromResult(resultUserID, "SESSIONID");
        String clientId = getValueFromResult(resultUserID, "CLIENTID");
        String userLoginId = getValueFromResult(resultUserID, "USERLOGINID");
        Assertions.assertNotNull(userID, "Can't get userID from cache. Stopping...");
        Assertions.assertNotNull(sessionId, "Can't get sessionId from cache. Stopping...");
        Assertions.assertNotNull(clientId, "Can't get clientId from cache. Stopping...");
        Assertions.assertNotNull(userLoginId, "Can't get clientId from cache. Stopping...");
        harness.store("USERID", userID);
        harness.store("SESSIONID", sessionId);
        harness.store("CLIENTID", clientId);
        harness.store("USERLOGINID", userLoginId);
    }

    public void storeDocumentUploaderCode() {
        harness.getEndpoint(NewIbEndpoint.class).sleep(TimeUnit.SECONDS, 2);
        Result<Record> resultUserID = harness.getEndpoint(UdebsEndpoint.class)
                .executeSql(ChildBuildingSavingsSQL.SQL_GET_DU_URL
                        .replaceAll("_SESSIONID_", harness.get("SESSIONID")));
        String code = getValueFromResult(resultUserID, "CODE");
        Assertions.assertNotNull(code, "Can't get Document Uploader CODE from CBL Journal. Stopping...");
        harness.log(String.format("CODE: %s", code));
        harness.store("CODE", code);
    }

    public static String getValueFromResult(Result<Record> result, String identifier) {
        return result.stream()
                .findFirst()
                .map(x -> x.getValue(identifier).toString())
                .orElse(null);
    }
}
