package cz.moneta.test.dsl.hypos.pages.contract.approval;

import cz.moneta.test.dsl.Harness;
import cz.moneta.test.dsl.hypos.components.Menu;
import cz.moneta.test.dsl.hypos.pages.HyposPageFlow;
import cz.moneta.test.dsl.util.DateUtils;
import cz.moneta.test.dsl.util.data.hypos.HyposContract;
import cz.moneta.test.harness.context.StoreAccessor;
import cz.moneta.test.harness.endpoints.hypos.HyposEndpoint;
import cz.moneta.test.harness.support.web.AcceptAlert;
import cz.moneta.test.harness.support.web.CheckElementPresent;
import cz.moneta.test.harness.support.web.Click;
import cz.moneta.test.harness.support.web.CustomAction;
import cz.moneta.test.harness.support.web.Until;
import cz.moneta.test.harness.support.web.Wait;
import cz.moneta.test.harness.support.web.Waits;

import static cz.moneta.test.dsl.hypos.pages.contract.approval.ScoringPage.PAGE_TITLE;
import static cz.moneta.test.dsl.hypos.tasks.HyposTasks.defaultDateFormat;

@Wait(PAGE_TITLE)
public interface ScoringPage extends HyposPageFlow<ScoringPage>, Menu, StoreAccessor {
    String PAGE_TITLE = "//h1[text()='Schvalování']";
    String MANUAL_SCORING_LINK = "//a[text()='Předat na scoring - manuál']";
    String AUTOMAT_SCORING_LINK = "//a[text()='Předat na scoring - automat']";
    String SEND_TO_SCORING_BUTTON = "//button[contains(text(),'Odeslat na scoring')]";
    String APPROVAL_TYPE_SCORING_TD = "//div[@id='scoring-list']//td[text()='Scoring']";
    String APPROVE_TAB_LINK = "//li[@role='tab']/a[text()='Schvalování']";
    String ELECTRONIC_APPROVAL_PROTOCOL_RADIO_NO = "//input[@id='electronic_approval_protocol_no']";
    String APPROVE_CONTRACT_LINK = "//form[@id='approveForm']//a[text()='Schválit obchod']";
    String UW_CHECKS_DIV = "//div[@id='uw-checks']";
    String NAS_ONGOING_CHECKS_DIV = UW_CHECKS_DIV + "//div[@class='nas-uw-check-loading']";
    String CONFIRM_APPROVAL_BUTTON = UW_CHECKS_DIV + "//button[text()='Dokončit schválení']";
    String AP_VERIFICATION_BUTTON = "//a[text()='Doplň doklady']";
    String CANCEL_CONTRACT_BUTTON = "//a[text()='Ukončit obchod']";
    String SCORING_AP_DETAIL_BUTTON = "//div[@id='scoring-list']//a[text()='%s']";
    String SCORING_AP_ID = "//div[@id='scoring-list']//td[text()='Scoring']/following-sibling::td/a[contains(@href,'approve.result')]";
    String CONTRACT_APPROVED_TEXT = "//td[text()='Schválení UW']//following-sibling::td[contains(text(), 'Schváleno')]";

    String CONDITION_FORM = "//form[@id='condition']";
    String CONDITION_DETAIL = "//a[contains(text(),'%s')]";
    String CONDITION_FULFILLMENT_DATE_INPUT = CONDITION_FORM + "//input[@name='tce_date']";
    String CONDITION_SAVE_BUTTON = CONDITION_FORM + "//button[text()='Uložit']";

    String AP_ID = "AP_ID";

    @CustomAction
    default ScoringChecklistPage clickManualScoring() {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        endpoint.click(() -> MANUAL_SCORING_LINK);
        endpoint.acceptAlert(20);
        return null;
    }

    @Click(AUTOMAT_SCORING_LINK)
    ScoringChecklistPage clickAutomatScoring();

    @Wait(value = LOADER, waitSecondsForElement = 30, until = Until.GONE)
    @Wait(value = LOADER, waitSecondsForElement = 30, until = Until.GONE)
    @Wait(value = LOADER, waitSecondsForElement = 30, until = Until.GONE)
    @Click(SEND_TO_SCORING_BUTTON)
    ScoringPage clickSendToScoringButton();

    @Click(AP_VERIFICATION_BUTTON)
    ApVerificationPage clickToApVerification();

    @Click(value = SCORING_AP_DETAIL_BUTTON, isStringDynamicXpath = true)
    ScoringDetailPage clickScoringDetail(String scoringApId);

    @Click(CANCEL_CONTRACT_BUTTON)
    CancelContractPage clickToCancelContract();

    @Wait(value = APPROVAL_TYPE_SCORING_TD, until = Until.VISIBLE, waitSecondsForElement = 60)
    @CheckElementPresent(APPROVAL_TYPE_SCORING_TD)
    ScoringPage checkScoringApprovalPresent();

    @Click(value = APPROVE_TAB_LINK, andWait = @Wait(value = LOADER, until = Until.GONE))
    ScoringPage clickApproveTab();

    @Click(ELECTRONIC_APPROVAL_PROTOCOL_RADIO_NO)
    ScoringPage checkElectronicApprovalProtocolNo();

    @Click(APPROVE_CONTRACT_LINK)
    @AcceptAlert(waitSecondsForAlert = 30)
    ScoringPage clickApproveContractButton();

    @Waits({
        @Wait(value = LOADER, waitSecondsForElement = 60, until = Until.GONE),
        @Wait(value = NAS_ONGOING_CHECKS_DIV, waitSecondsForElement = 60, until = Until.GONE),
        @Wait(value = LOADER, waitSecondsForElement = 30, until = Until.GONE)
    })
    @Click(CONFIRM_APPROVAL_BUTTON)
    @AcceptAlert(waitSecondsForAlert = 30)
    ScoringPage waitAndClickConfirmApprovalButton();

    @Waits({
        @Wait(value = CONTRACT_APPROVED_TEXT, waitSecondsForElement = 120, until = Until.VISIBLE),
        @Wait(value = LOADER, waitSecondsForElement = 30, until = Until.GONE),
        @Wait(value = CONTRACT_HOMEPAGE_LINK, waitSecondsForElement = 30, until = Until.CLICKABLE)
    })
    ScoringPage waitUntilContractApproved();

    @CustomAction
    default ScoringPage getApId(Harness harness) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        harness.store(AP_ID, endpoint.getText(SCORING_AP_ID));
        return null;
    }

    @CustomAction
    default ScoringPage setConditionsFulfillmentDate(HyposContract hyposContract) {
        HyposEndpoint endpoint = getEndpoint(HyposEndpoint.class);
        for (int i = 0; i < hyposContract.getDrawingConditions().size(); i++) {
            if (hyposContract.getDrawingConditions().get(i).getType() != null) {
                String condition = String.format(CONDITION_DETAIL, hyposContract.getDrawingConditions().get(i).getCondition());
                endpoint.click(() -> condition);
                endpoint.waitForElementsToLoad(20, Until.VISIBLE, CONDITION_FULFILLMENT_DATE_INPUT);
                endpoint.type(() -> CONDITION_FULFILLMENT_DATE_INPUT, DateUtils.getTodayDateIncrementedByDays(60, defaultDateFormat), true);
                endpoint.click(() -> CONDITION_SAVE_BUTTON);
                endpoint.acceptAlert(20);
            }
        }
        return null;
    }
}