//Асинхронщина в JS, callback hell
//Задание
let request = new XMLHttpRequest();
let selectCountry = document.querySelector("#country");
let selectCity    = document.querySelector("#city");

request.open("GET", "https://raw.githubusercontent.com/David-Haim/CountriesToCitiesJSON/master/countriesToCities.json", true);

request.addEventListener("readystatechange", function() {
    if(request.readyState == 4) {
        let countriesToCitiesJSON = JSON.parse(request.response);

        drawCountriesInSelect(countriesToCitiesJSON);
        drawCityInSelect(countriesToCitiesJSON);

        selectCountry.addEventListener("input", function() {
            drawCityInSelect(countriesToCitiesJSON);
        });
    }
});

request.send();

let drawCountriesInSelect = function(obj) {
    for(let [key, value] of Object.entries(obj)) {
        let option = document.createElement("option");

        option.text = key;

        selectCountry.appendChild(option);
    }
}

let drawCityInSelect = function(obj) {
    let countryIndex = selectCountry.selectedIndex;
    let str = "";

    for(let city of Object.entries(obj)[countryIndex][1]) {
        str += `<option>${city}</option>`;
    }

    selectCity.innerHTML = str;
}


//Javascript Async: Promise Homework
//fetch basic
//fetch improved
let container = document.querySelector(".contanier");

function Table(container, url) { // Конструктор для сбора таблицы
    this.url = url;         

    let getObjForFetchRequest = function(url) {     // Получаю obj в зависимости от url, по факту эта функция запускает всю цепочку событий по отрисовки таблицы
        fetch(url).then(res => res.json()).then(obj => createTable(obj));
    };

    let valueCreators = { // Тут я буду проверять кем является value, в цыкле for у функции createTable, строка или массив
        String(value) {
            if(value.includes("https://swapi.dev/api/")) { // Проверка на наличие строки "https://swapi.dev/api/" в value, если true то ложу в кнопку
                return `<button>${value}</button>`;
            } else {
                return value;
            }
        },
        Array(value) {
            let str = "";

            for(let item of value) {
                if(item.includes("https://swapi.dev/api/")) {
                    str += `<button>${item}</button><br>`;
                } else {
                    str += item;
                }
            }

            return str;
        }
    };

    let createTable = function(obj) { // Собсна функция которая собирает таблицу
        let str = "";

        str += "<table>";

        for(let [key, value] of Object.entries(obj)) {
            let valueCreatorFunction = valueCreators[value.constructor.name];

            str += `<tr><td>${key}</td><td>${valueCreatorFunction(value)}</td></tr>`; // Запуск valueCreatorFunction что бы корректно отрисовать строку или массив
        };

        str += "</table>";

        container.innerHTML = str;
    };

    getObjForFetchRequest(url); // Одноразовый вызов функции для запуска цепочки по отрисовки таблицы 

    let changeObjForFetchRequest = function(evt) { // Функция для слушателя событий "click" который будет запускать getObjForFetchRequest с url который находиться внутри кнопки
        if(evt.target.tagName == "BUTTON") {
            getObjForFetchRequest(evt.target.textContent);
        }
    }

    container.addEventListener("click", changeObjForFetchRequest); 
};

let table = new Table(container, "https://swapi.dev/api/people/1/");


//myfetch
function myfetch(url){
    return new Promise(function (resolve, reject){
        let xhr = new XMLHttpRequest();

        xhr.open("GET", url, true);

        xhr.addEventListener("readystatechange", function() {
            if(xhr.readyState == 4) {               // Если все хорошо то нужно передать в resolve объект
                resolve(JSON.parse(xhr.response));
            } else if (xhr.status > 500) {          // Если все не очень хорошо то вывести информацию об ошибке
                reject(`Ошибка: ${xhr.status} ${xhr.statusText}`);
            }
        });

        xhr.send();
    })
}

myfetch('https://swapi.dev/api/people/1/')
  .then(luke => console.log(luke));


//race
let delay = new Promise((resolve, reject) => {
    setTimeout(() => resolve("delay"), 500); // Подобрать параметр delay так, что бы результат был неизвестен изначально не возможно, иногда myfetch выполняется 1-2 сек, а иногда 9 сек
});
  
Promise.race([myfetch('https://swapi.dev/api/people/1/'), delay]).then(value => console.log(value));