package cz.moneta.test.dsl.util.task.ufo.operations;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.ufo.operations.recorder.CRC710_S001_RecorderMainPage;
import cz.moneta.test.dsl.ufo.operations.recorder.RecorderNameOfGroup;

import java.util.function.Function;
import java.util.stream.Stream;

public class RecorderTasks {

    private final Harness harness;

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

    public Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> addMultipleMmbOmRetailWrites(String requestName,
                                                                                                             String reasonName,
                                                                                                             int writesNumber) {
        return start -> start.then(addMultipleMmbOmRetailRequests(requestName, writesNumber))
                .then(addMultipleReasons(reasonName, writesNumber));
    }

    public Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> openCategories(RecorderNameOfGroup... categoriesNames) {
        return Stream.iterate(0, n -> n + 1)
                .limit(categoriesNames.length)
                .map(n -> openCategory(categoriesNames[n]))
                .reduce(Function.identity(), Function::andThen);
    }

    public Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> selectCustomerByRc(String rc) {
        return start -> start.clickBirthNumberInSubject()
                .fillSearchSubjectInput(rc)
                .clickLoadSubjectArrow();
    }

    public Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> submitBulkWrite() {
        return start -> start.submitRequest()
                .waitForSubjectNameVanish();
    }

    private static Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> addMultipleMmbOmRetailRequests(String requestName, int writesNumber) {
        return Stream.iterate(1, n -> n + 1)
                .limit(writesNumber)
                .map(n -> addWrite(requestName, n))
                .reduce(Function.identity(), Function::andThen);
    }

    private static Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> addMultipleReasons(String reasonName, int writesNumber) {
        return Stream.iterate(1, n -> n + 1)
                .limit(writesNumber)
                .map(n -> addReason(reasonName, (writesNumber + 1) - n))
                .reduce(Function.identity(), Function::andThen);
    }

    private static Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> addWrite(String writeName, int number) {
        return start ->
                start.openItemInTreeMenu(writeName)
                        .waitForNextRecordInsertion(number);
    }

    private static Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> openCategory(RecorderNameOfGroup categoryName) {
        return start -> start.openGroupInTreeMenu(categoryName);
    }

    private static Function<CRC710_S001_RecorderMainPage, CRC710_S001_RecorderMainPage> addReason(String reasonName, int number) {
        return start ->
                start.addSolution(reasonName)
                        .waitForReasonInsertion(number);
    }
}
