import {error} from "winston";
import {ParseData} from "./parse-data";
import logger from "../reporting-helpers/logger";
import {StringHelper} from "./string-helper";
import {DataHelper} from "./data-helper";
import {PageConfigTypes} from "../../custom-types/pageConfig-types";

export class ConfigHelper {

    public static isPageMappedInTheFramework(pageId: string, pageConfig: Record<string, string>): boolean {
        logger.info(`Page name : ${pageId}`);
        const pageKeys = Object.keys(pageConfig);
        let matchedPageId: string;
        matchedPageId = pageKeys.find(pageKey => pageKey.trim() === pageId);
        return !(matchedPageId === undefined)
    }

    public static getValueFromJsonFileUsingKey(pageConfig: Record<string, string>, userKey: string): string {
        const requiredValue: string = pageConfig[userKey];
        if (requiredValue === undefined)
            throw error(`${userKey} does not exists`)
        return requiredValue;
    }

    public static getLocatorFromCurrentPage(componentName: string, elementKey: string, data: {
        [k: string]: any
    } = {}): string {

        const componentElementMappingDir = ParseData.getEnvData('PAGE_ELEMENTS_PATH');
        const currentComponentElementMappings = `${componentElementMappingDir}${componentName}.json`
        const currentComponentElementConfig = ParseData.getJsonFromFile(currentComponentElementMappings);

        const commonComponentElementMappings = `${componentElementMappingDir}common.json`
        const commonComponentElementConfig = ParseData.getJsonFromFile(commonComponentElementMappings);

        if (currentComponentElementConfig[elementKey] === undefined) {
            logger.info(`Element "${componentName}.${elementKey}" is NOT FOUND in mapping file : "${currentComponentElementMappings}"`)
            logger.info(`Checking element "${componentName}.${elementKey}" in mapping file : "${commonComponentElementMappings}"`)
            if (commonComponentElementConfig[elementKey] === undefined) {
                logger.error(`Element "${componentName}.${elementKey}" is NOT FOUND in mapping file : "${commonComponentElementMappings}" as well`)
                throw Error(`Element "${componentName}.${elementKey}" is NOT FOUND neither in "${currentComponentElementMappings}" nor in "${commonComponentElementMappings}"`);
            } else {
                logger.info(`Element "${componentName}.${elementKey}" is FOUND in mapping file : "${commonComponentElementMappings}"`)
                return this.generateLocatorForSelectedComponent(commonComponentElementMappings, elementKey, data);
            }

        } else {
            logger.info(`Element "${componentName}.${elementKey}" is FOUND in mapping file : "${currentComponentElementMappings}"`)
            return this.generateLocatorForSelectedComponent(currentComponentElementMappings, elementKey, data);
        }
    }

    public static generateLocatorForSelectedComponent(fileLocation: string, elementKey: string, data: {
        [k: string]: any
    } = {}): string {
        let locatorsArray = [];
        let masterLocator: string = "";
        const absoluteFileLocation = `${process.cwd()}${fileLocation}`;
        const jsonData = require(absoluteFileLocation);
        let isDynamicPatternFound: boolean = false;

        for (const kv of Object.keys(jsonData)) {
            if (kv.trim() === elementKey) {
                const myParentLocator = jsonData[kv];

                for (const myKey of Object.keys(myParentLocator)) {
                    if (myKey === 'dynamicPattern') {
                        isDynamicPatternFound = true;
                        logger.info(`Building locator using dynamic pattern, for element ${elementKey}`);
                        continue;
                    }
                    const newKey = (myKey === 'parent-data-test-id') ? 'data-test-id' : myKey;
                    let locator = null;
                    if (myKey === 'parent-data-test-id')
                        locator = (newKey === 'css' || newKey === 'xpath') ? myParentLocator[newKey] : `//*[@${newKey}='${myParentLocator[myKey]}']`
                    else if (myKey === 'custom-path')
                        locator = myParentLocator[newKey]
                    else
                        locator = (newKey === 'css' || newKey === 'xpath') ? myParentLocator[newKey] : `//*[@${newKey}='${myParentLocator[newKey]}']`
                    locatorsArray.push(locator);
                }
            }
        }
        masterLocator = locatorsArray.join('');
        masterLocator = (isDynamicPatternFound && DataHelper.isKeyExistsInMyCollection(data, 'param')) ? (masterLocator.replaceAll('?', DataHelper.getValueFromCollection(data, 'param'))) : masterLocator;
        logger.info(`Master Locator for element "${elementKey}" : ${masterLocator}`);
        return masterLocator;
    }


    public static getCurrentPageId(currentUrl: string): string {
        // const currentUrl = await getCurrentUrl();
        const allResources = currentUrl.split('/');
        const resourcesCount = allResources.length;
        let currentPageId = allResources[resourcesCount - 1];
        return (currentPageId === "") ? "home" : currentPageId;
    }

    public static getPageConfig(pageObject: string, data: { [k: string]: any } = {}): PageConfigTypes {
        let componentName: string = "common"
        let elementKey: string = "";

        if (pageObject.split('.').length === 1) {
            logger.info(`Working with common elements : "${pageObject}"`)
            elementKey = pageObject.split('.')[0];
        } else if (pageObject.split('.').length === 2) {
            componentName = pageObject.split('.')[0]
            elementKey = pageObject.split('.')[1];
        } else
            throw Error(`PageObject "${pageObject}" is NOT in correct format "element" or "page.element"`);

        let selector = ConfigHelper.getLocatorFromCurrentPage(componentName, elementKey, data);
        return {pageId: componentName, elementKey: elementKey, selector: selector, param: data}
    }
}
