import logger from "../reporting-helpers/logger";
import {ParseData} from "./parse-data";
import {ConfigHelper} from "./config-helper";
import getCurrentUrl from "../framework-helpers/action/getCurrentUrl";
import openUrl from "../framework-helpers/action/openUrl";
import {CustomExpect} from "./custom-expect";
import pause from "../framework-helpers/action/pause";
import scriptExecute from "../framework-helpers/action/scriptExecute";
import {browser, $, $$, expect} from '@wdio/globals'

export class browserHelper {
// This function is used to clear the browser instance(localStorage & sessionStorage)
    public static clearBrowserStorage() {
        function clearLocalAndSessionStorage() {
            window.sessionStorage.clear();
            window.localStorage.clear();
        }

        return browser.execute(clearLocalAndSessionStorage);
    }

    public static async currentPage(pageId: string, falseCase: boolean = false, maxCheckCounter: number = 10, checkInterval: number = 1000) {
        const pageUrlPath = ParseData.getEnvData('PAGE_URLS_PATH');
        const pageConfig = ParseData.getJsonFromFile(pageUrlPath);
        CustomExpect.expectToBeTruthy(ConfigHelper.isPageMappedInTheFramework(pageId, pageConfig), `Page "${pageId}" is not mapped in "./config/pages.json"`);
        let isPageLoadSuccess: boolean = false;
        let counter: number = 0;
        let currentUrl: string;
        const expectedPageResources: string = pageConfig[pageId];
        logger.info(`Expected page resource is ${falseCase ? 'not' : ''} "${expectedPageResources}"`);

        do {
            await pause(1000);
            currentUrl = await getCurrentUrl();
            logger.info(`Verifying URLS now`);
            try {
                if (!falseCase)
                    CustomExpect.expectToMatch(currentUrl, expectedPageResources, `Current URL "${currentUrl}" is not MATCHING with expected URL "${expectedPageResources}"`)
                else
                    CustomExpect.expectNotToMatch(currentUrl, expectedPageResources, `Current URL "${currentUrl}" is MATCHING with expected URL "${expectedPageResources}"`)
                isPageLoadSuccess = true;
            } catch (e) {
                await pause(checkInterval);
                logger.info(`User is not on the expected page. Please wait...`)
                counter++;
            }
        } while (isPageLoadSuccess == false && counter <= maxCheckCounter)
        CustomExpect.expectToBeTruthy(isPageLoadSuccess, `User is ${falseCase ? '' : 'not'} on the "${pageId}" page`)
        logger.info(`Verified : User is ${falseCase ? 'not' : ''} on the "${pageId}" page now`);
    }


    public static async exactPage(pageId: string, falseCase: boolean = false, maxCheckCounter: number = 10, checkInterval: number = 1000) {
        //await this.waitUntilPageLoadedSuccessfully(5000);
        const pageUrlPath = ParseData.getEnvData('PAGE_URLS_PATH');
        const pageConfig = ParseData.getJsonFromFile(pageUrlPath);
        CustomExpect.expectToBeTruthy(ConfigHelper.isPageMappedInTheFramework(pageId, pageConfig), `Page "${pageId}" is not mapped in "./config/pages.json"`);
        let isPageLoadSuccess: boolean = false;
        let counter: number = 0;
        let currentUrl: string;
        const expectedPageResources: string = ParseData.getEnvData("HOST_URL") + pageConfig[pageId];
        logger.info(`Expected page resource is ${falseCase ? 'not' : ''} "${expectedPageResources}"`);

        do {
            await pause(checkInterval);
            currentUrl = await getCurrentUrl();
            logger.info(`Verifying URLS now...`);
            try {
                if (!falseCase)
                    CustomExpect.expectToEqual(currentUrl, expectedPageResources, `Current URL "${currentUrl}" is not equal with expected URL "${expectedPageResources}"`)
                else
                    CustomExpect.expectNotToEqual(currentUrl, expectedPageResources, `Current URL "${currentUrl}" is equal with expected URL "${expectedPageResources}"`)
                isPageLoadSuccess = true;
            } catch (e) {
                await pause(checkInterval);
                logger.info(`User is not on the expected page. Please wait...`)
                counter++;
            }
        } while (isPageLoadSuccess == false && counter <= maxCheckCounter)
        CustomExpect.expectToBeTruthy(isPageLoadSuccess, `User is ${falseCase ? '' : 'not'} on the "${pageId}" page`)
        logger.info(`Verified : User is ${falseCase ? 'not' : ''} on the "${pageId}" page now`);
    }

    public static async navigateToPageFromHost(pageId: string, hostName: string = "HOST_URL", clearCacheAndStorage: boolean = true) {
        const pageUrlPath = ParseData.getEnvData('PAGE_URLS_PATH');
        const pageConfig = ParseData.getJsonFromFile(pageUrlPath);
        // expect(ConfigHelper.isPageMappedInTheFramework(pageId, pageConfig)).toBeTruthy();
        CustomExpect.expectToBeTruthy(ConfigHelper.isPageMappedInTheFramework(pageId, pageConfig), `Page "${pageId}" is not mapped in "./config/pages.json"`);

        const pageResourcesFromPageConfig = pageConfig[pageId];
        logger.info(`Page Resource from Config >>> ${pageResourcesFromPageConfig}`);

        const hostUrl = ParseData.getEnvData(hostName.toUpperCase());

        const targetUrl = `${hostUrl}${pageResourcesFromPageConfig}`;
        //revisit this line
        logger.info(`Clear cache : ${clearCacheAndStorage}`)
        clearCacheAndStorage ? await openUrl(targetUrl) : await scriptExecute('window.history.pushState("", "", "' + targetUrl + '")');
    }

    public static async navigateUsingDeepLink(deepLink: string, hostName: string = "HOST_URL") {
        const hostUrl = ParseData.getEnvData(hostName.toUpperCase());
        const targetUrl = `${hostUrl}${deepLink}`;
        logger.info(`Target URL : ${targetUrl}`);
        await openUrl(targetUrl);
    }

    public static async waitForAllAureliaComponentLoaded() {
        await browser.waitUntil(async () => {
            let componentsLoadedInfo = await browser.execute(() => {
                //@ts-ignore
                return (typeof document.__aureliaGlobal !== 'undefined' && document.aureliaAllComposed === true)
            });
            return componentsLoadedInfo;
        }, {
            timeout: parseInt(ParseData.getEnvData('PAGE_LOAD_TIMEOUT_MS')),
            interval: parseInt(ParseData.getEnvData('MAX_TRY')),
            timeoutMsg: 'Not all components loaded'
        });
    }
}
