import config from './config.js';
import Nightmare from 'nightmare';
import selectors from './selectors.js';

function child(selector, childNumber) {
    let aux = selector.split(' ');
    return selector.replace(aux[0], `${aux[0]}:nth-child(${childNumber})`);
}

Nightmare.action('login', function(done) {
    this.goto(`${config.url}auth/?apiKey=salix`)
    .wait(selectors.login.textFieldInput)
    .write(`${child(selectors.login.textFieldInput, 1)}`, 'JessicaJones')
    .write(`${child(selectors.login.textFieldInput, 2)}`, 'nightmare')
    .click(selectors.login.submitButton)
    .wait(1000) // should create an extension like: https://github.com/segmentio/nightmare/issues/481 to wait for dom to be ready.
    .then(done);
});

Nightmare.action('getInnerText', function(selector, done) {
    this.wait(selector)
    .evaluate_now(function(elementToSelect) {
        return document.querySelector(elementToSelect).innerText;
    }, done, selector);
});

Nightmare.action('getInputValue', function(selector, done) {
    this.wait(selector)
    .evaluate_now(function(elementToSelect) {
        return document.querySelector(elementToSelect).value;
    }, done, selector);
});

Nightmare.action('clearInput', function(selector, done) {
    let backSpaces = [];
    for (let i = 0; i < 50; i += 1) {
        backSpaces.push('\u0008');
    }
    this.wait(selector)
    .type(selector, backSpaces.join(''))
    .then(done);
});

Nightmare.action('write', function(selector, text, done) {
    this.wait(selector)
    .type(selector, text)
    .then(done);
});

Nightmare.action('waitToClick', function(selector, done) {
    this.wait(selector)
    .click(selector)
    .then(done);
});

Nightmare.action('isVisible', function(selector, done) {
    this.wait(selector)
    .evaluate_now(elementSelector => {
        const selectorMatches = document.querySelectorAll(elementSelector);
        const element = selectorMatches[0];
        if (selectorMatches.length > 1) {
            throw new Error(`multiple matches of ${elementSelector} found`);
        }
        let isVisible = false;
        if (element) {
            const eventHandler = event => {
                event.preventDefault();
                isVisible = true;
            };
            element.addEventListener('mouseover', eventHandler);
            const elementBoundaries = element.getBoundingClientRect();
            const x = elementBoundaries.left + element.offsetWidth / 2;
            const y = elementBoundaries.top + element.offsetHeight / 2;
            const elementInCenter = document.elementFromPoint(x, y);
            const elementInTopLeft = document.elementFromPoint(elementBoundaries.left, elementBoundaries.top);
            const elementInBottomRight = document.elementFromPoint(elementBoundaries.right, elementBoundaries.bottom);
            const e = new MouseEvent('mouseover', {
                view: window,
                bubbles: true,
                cancelable: true
            });
            if (elementInCenter) {
                elementInCenter.dispatchEvent(e);
            }
            if (elementInTopLeft) {
                elementInTopLeft.dispatchEvent(e);
            }
            if (elementInBottomRight) {
                elementInBottomRight.dispatchEvent(e);
            }
            element.removeEventListener('mouseover', eventHandler);
        }
        return isVisible;
    }, done, selector);
});

Nightmare.action('selectText', function(selector, done) {
    this.wait(selector)
    .evaluate(elementToSelect => {
        const range = document.createRange();
        range.selectNodeContents(document.querySelector(elementToSelect));
        const sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }, selector)
    .mouseup(selector)
    .then(done);
});

Nightmare.action('countSearchResults', function(selector, done) {
    this.evaluate_now(selector => {
        return document.querySelectorAll(selector).length;
    }, done, selector);
});

Nightmare.action('waitForNumberOfElements', function(selector, count, done) {
    this.wait((resultSelector, expectedCount) => {
        return document.querySelectorAll(resultSelector).length === expectedCount;
    }, selector, count)
    .then(done);
});

Nightmare.action('waitForTextInElement', function(selector, name, done) {
    this.wait((resultSelector, expectedName) => {
        return document.querySelectorAll(resultSelector)[0].innerText.toLowerCase().includes(expectedName.toLowerCase());
    }, selector, name)
    .then(done);
});

Nightmare.action('waitForSnackbarReset', function(done) {
    this.wait(() => {
        return document.querySelector('vn-snackbar').innerText === '';
    })
    .then(done);
});

Nightmare.action('waitForURL', function(hashURL, done) {
    this.wait(hash => {
        return document.location.hash.includes(hash);
    }, hashURL)
    .then(done);
});