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

/**
 * Check if the given element is visible inside the current viewport
 * @param  falseCase->false Check if expected state of the element is reached
 * @param  falseCase->true Check if expected state of the element is NOT reached
 * @param  expectedElementState 'Clickable'|'Displayed'|'Selected'|'Existing'|'Enabled'|'Focused'|'Checked'
 * @param  {number}   maxTryCount Max try count
 * @param  {number}   checkIntervalInMs Internal between tries
 */

export default async function (pageConfig: PageConfigTypes, falseCase: boolean, expectedElementState: string, maxTryCount = 10, checkIntervalInMs: number = 1000,
) {
    let isExpectedStateFound: boolean = false;
    let tryCounter: number = 0;
    let actualElementState: boolean;

    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 {
        //@ts-ignore
        actualElementState = await $(pageConfig.selector)[waitCommand]();
        //actualElementState - returned true
        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}" is ${falseCase ? '' : 'not '}"${expectedElementState}"`)
}
