import pause from "./pause";
import logger from "../../reporting-helpers/logger";
import {PageConfigTypes} from "../../../custom-types/pageConfig-types";
import {CustomExpect} from "../../common-helpers/custom-expect";
import {browser, $, $$, expect} from '@wdio/globals'

/**
 * Check if the given element is visible inside the current viewport
 * @param  {number}   elementPosition  Passed to the function should be >= 1
 *                                     index - will be calculated and adjusted accordingly
 * @param  {String}   selector   Element selector
 * @param  {String}   falseCase Whether to check if the element by Index is visible
 *                              within the current viewport or not
 * @param  {String}   waitCommand
 * isExisting : Returns true if element exists in the DOM. For example, you can have an element present, but it may have the hidden clause on it.
 * isDisplayed : Return true only if the selected DOM-element is displayed.
 * @param  {number}   maxTryCount
 * @param  {number}   checkIntervalInMs
 */


export default async (elementPosition: number, pageConfig: PageConfigTypes, falseCase: boolean, expectedElementState: string, maxTryCount = 5, checkIntervalInMs: number = 1000,
) => {
    let isExpectedStateFound: boolean = false;
    let tryCounter: number = 0;
    let allElements;
    const index = elementPosition - 1;

    let myMaxTryCount = parseInt(process.env["MAX_TRY"]) || maxTryCount;
    let myIntervalsInMs = parseInt(process.env["INTERVALS_MS"]) || checkIntervalInMs;

    logger.info(`Wait -> Max Try Counter is set to "${myMaxTryCount}"`);
    logger.info(`Wait -> Interval is set to "${myIntervalsInMs}" Ms`);

    if (
        expectedElementState.trim() !== 'Clickable' &&
        expectedElementState.trim() !== 'Displayed' &&
        expectedElementState.trim() !== 'Selected' &&
        expectedElementState.trim() !== 'Existing' &&
        expectedElementState.trim() !== 'Enabled' &&
        expectedElementState.trim() !== 'Focused' &&
        expectedElementState.trim() !== 'Checked'
    )
        throw new Error(`Invalid selection for "WaitForElementState" function. Valid selection is "Clickable || "Displayed || "Selected" || "Existing" || "Enabled" || "Focused" || "Checked"`);
    let waitCommand = `is${expectedElementState}`;
    waitCommand = (waitCommand === 'isChecked') ? 'isSelected' : waitCommand;
    await pause(myIntervalsInMs);
    do {
        let element = await $$(pageConfig.selector)[index];
        let actualElementState: boolean = (element !== null) ? (await (element !== undefined) ? await element[waitCommand]() : false) : false;
        if (actualElementState === true) {
            //set true if expected is true
            isExpectedStateFound = !falseCase ? true : false;
            break;
        } else { //actualElementState - returned not true
            if (falseCase && tryCounter === myMaxTryCount) {
                isExpectedStateFound = true;
                break;
            }
            logger.info(`Element "${pageConfig.pageId}.${pageConfig.elementKey}" is not loaded yet`);
            await pause(myIntervalsInMs);
            tryCounter++;
            continue;
        }
    } while (!isExpectedStateFound && tryCounter <= myMaxTryCount);

    CustomExpect.expectToBeTruthy(isExpectedStateFound, `Element "${pageConfig.pageId}.${pageConfig.elementKey}" at index "${index}" is ${falseCase ? '' : 'not '}"${expectedElementState}"`)
}



