// Class Work (Telegram)
const getGQL = url => async (query, variables) => {
    return await fetch(url, {
        method: 'POST',
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({ query, variables })
    })
        .then(res => res.json())
        .then(data => {
        if (!data.data && data.errors)
            throw new Error(JSON.stringify(data.errors))
        return data.data[Object.keys(data.data)[0]]
    })
}
const gql = getGQL('http://shop-roles.asmer.fs.a-level.com.ua/graphql');
(async () => {
    let result = await gql(`query cats ($q:String) {CategoryFind(query: $q){name goods{name images{url}}}}`,{"q": "[{}]"});
    let div = document.createElement('div');
    for (const key in result) {
        let p = document.createElement('p');
        let str = '<ul>';
        for (const keys in result[key]['goods']) {
            str += `<li>${result[key]['goods'][keys]['name']}</li>`;
        }
        str += '</ul>';
        p.innerHTML = `<strong>${key}:</strong> ${result[key]['name']} ${str}`;
        div.append(p);
    }
    document.body.append(div);
})()

// Светофор
const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms));
async function trafficLight(container, delayGreen, delayYellow, delayRed){
    let green = document.createElement('div');
    let yellow = document.createElement('div');
    let red = document.createElement('div');
    green.className = 'lighter__elem';
    yellow.className = 'lighter__elem';
    red.className = 'lighter__elem';
    container.append(green, yellow, red);

    while (true){
        yellow.style.backgroundColor = '#696969FF';
        green.style.backgroundColor = '#309600';
        await delay(delayGreen)
        green.style.backgroundColor = '#696969FF';
        yellow.style.backgroundColor = '#e2e83c';
        await delay(delayYellow)
        yellow.style.backgroundColor = '#696969FF';
        red.style.backgroundColor = '#b93c00';
        await delay(delayRed)
        red.style.backgroundColor = '#696969FF';
        yellow.style.backgroundColor = '#e2e83c';
        await delay(delayYellow)
    }
}
(async () => {
    await trafficLight(lighter, 10000, 5000, 10000);
})();

// domEventPromise
async function domEventPromise(element, eventName) {
    return new Promise(async (resolve, reject) => {
        try {
            element.addEventListener(eventName.toLowerCase(), async (e) => {
                await resolve(e);
                element.removeEventListener(eventName.toLowerCase(), this);
            })
        } catch (err) {
            await reject(err);
        }
    })
}
domEventPromise(knopka, 'click').then(e => console.log('event click happens', e));

// PedestrianTrafficLight светофор для пешеходов
async function PedestrianTrafficLight() {
    let h = document.createElement('h1')
    h.textContent = 'Светофор для пешеходов синхронизированный с автомобильным светофором'
    h.style.textAlign = 'center'
    document.body.append(h);
    let container = document.createElement('div');
    let green = document.createElement('div');
    let red = document.createElement('div');
    let btn = document.createElement('button');
    green.className = 'lighter__elem';
    red.className = 'lighter__elem';
    red.style.backgroundColor = '#b93c00';
    green.style.backgroundColor = '#696969FF';
    container.className = 'container';
    btn.textContent = 'PedestrianTrafficLight';
    container.append(green, red, btn);
    document.body.append(container);

    let container2 = document.createElement('div');
    let greenAuto = document.createElement('div');
    let yellowAuto = document.createElement('div');
    let redAuto = document.createElement('div');
    greenAuto.className = 'lighter__elem';
    yellowAuto.className = 'lighter__elem';
    redAuto.className = 'lighter__elem';
    container2.className = 'container';
    container2.append(greenAuto, yellowAuto, redAuto);
    document.body.append(container2);

    while (true) {
        yellowAuto.style.backgroundColor = '#696969FF';
        greenAuto.style.backgroundColor = '#309600';
        btn.disabled = true;
        await delay(5000)
        greenAuto.style.backgroundColor = '#696969FF';
        yellowAuto.style.backgroundColor = '#e2e83c';
        btn.disabled = true;
        await delay(1000)
        yellowAuto.style.backgroundColor = '#696969FF';
        redAuto.style.backgroundColor = '#b93c00';
        btn.disabled = false;
        await Promise.race([
            domEventPromise(btn, 'click').then(async e => {
                red.style.backgroundColor = '#696969FF';
                green.style.backgroundColor = '#309600';
                btn.disabled = true;
                await delay(3000);
                green.style.backgroundColor = '#696969FF';
                red.style.backgroundColor = '#b93c00';
            }, err => console.log(err)),
            await delay(5000)]
        );
        redAuto.style.backgroundColor = '#696969FF';
        yellowAuto.style.backgroundColor = '#e2e83c';
        btn.disabled = true;
        await delay(1000)
    }
}
(async () => await PedestrianTrafficLight())()

// speedtest
async function speedtest(getPromise, count=1, parallel=1) {
    let duration, querySpeed, queryDuration, parallelSpeed, parallelDuration;
    let start = performance.now();  // duration
    let querySpeedArr = [];

    await (async () => {
        for (let i = 0; i < count; i++) {
            let arrPromise = []
            for (let j = 0; j < parallel; j++) {
                arrPromise.push(getPromise);
            }
            let querySpeedItemStart = performance.now();
            await Promise.all([...arrPromise.map(item => item())]);
            querySpeedArr.push(performance.now() - querySpeedItemStart);
        }
    })()

    duration = Math.round(performance.now() - start);
    querySpeed = (count * parallel) / 100000;
    queryDuration = querySpeedArr.reduce((a, b) => (a + b)) / querySpeedArr.length;
    parallelSpeed =  duration / (count * parallel) / 10000;
    parallelDuration = duration / (count * parallel);

    return {
        duration,           //общая длительность работы цикла
        querySpeed,         //реальная средняя скорость запроса
        queryDuration,      //реальное среднее время запроса
        parallelSpeed,      //скорость в запросах в миллисекунду
        parallelDuration    //среднее время обработки запроса параллельно
    }
}
speedtest(() => delay(1000), 10, 10).then(result => console.log(result))
speedtest(() => fetch('http://swapi.dev/api/people/1').then(res => res.json()), 10, 5).then(result => console.log(result));