/*fetch basic
Исследуйте сайт swapi.dev, рассмотрите JSON-ы, которые предоставляются этим сервисом (например: https://swapi.dev/api/people/1/, https://swapi.dev/api/people/2/, https://swapi.dev/api/starships/12/
С помощью следующего кода считать и вывести информацию о Люке Скайвокере:
fetch('https://swapi.dev/api/people/1/')
  .then(res => res.json())
  .then(luke => console.log(luke))
Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра:
DOM - элемент, в котором строится таблица
JSON, который нужно отобразить.*/
{
  function jsonToTable(parent = document.body, jsonObj){
      const jsonTable = document.createElement('table') //Создаём и добавляем в родительский єлемент будущую таблицу
      parent.append(jsonTable)

      for (const key in jsonObj){
          const tr = document.createElement('tr') //одно свойтсво - одна строка
          jsonTable.append(tr)
          const tdProperty = document.createElement('td') //столбик со свойствами обьекта
          tr.append(tdProperty)
          tdProperty.innerText = key
          const tdValue = document.createElement('td') // столбик со значениями свойств обьекта JSON
          tr.append(tdValue)
          tdValue.innerText = jsonObj[key]
      }
  }

  fetch('https://swapi.dev/api/people/1/')
.then(res => res.json())
.then(jsonObj => jsonToTable(document.body, jsonObj))
}

/* fetch improved
Расширить функцию отображения:
Если одно из полей строка или массив.
Если строки или строка содержат в себе https://swapi.dev/api/
То выводить вместо текста строки кнопку, при нажатии на которую:
делается fetch данных по этой ссылке
функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе.*/


{
  function buttonVisionText(button, element) {
    element.style.display = "block"

    button.innerText = 'Скрыть'
    button.style.backgroundColor = "SteelBlue"
    button.onclick = () => buttonHidetext(button, element)
  }

  function buttonHidetext(button, element) {
    element.style.display = "none"

    button.innerText = 'Показать'
    button.style.backgroundColor = "darkgrey"
    button.onclick = () => buttonVisionText(button, element)
  }

  function jsonToTable(parent = document.body, jsonObj) {
    const jsonTable = document.createElement('table') //Создаём и добавляем в родительский єлемент будущую таблицу
    parent.append(jsonTable)

    for (const key in jsonObj) {
      const tr = document.createElement('tr') //одно свойтсво - одна строка
      jsonTable.append(tr)

      const tdProperty = document.createElement('td') //столбик со свойствами обьекта
      tr.append(tdProperty)
      tdProperty.innerText = key

      const tdValue = document.createElement('td') // столбик со значениями свойств обьекта JSON
      tr.append(tdValue)
      //console.log(jsonObj[key])
      let regexp = /^\s*https?:\/\/./i; //тут проверяем является ли значение ссылкой

      if (regexp.test(jsonObj[key]) && typeof jsonObj[key] === "string") { //если значение ссылка но не массив

        const valueDiv = document.createElement('div') //div контейнер внутри ячейки
        tdValue.append(valueDiv)

        const button = document.createElement('button') // если да то создаём кнопку, текст изначально скрыт
        tdValue.append(button)
        button.innerText = 'Показать'

        //при первом нажатии получаем данные по ссылке, выводим в valueDiv

        button.onclick = () => {
          fetch(jsonObj[key])
            .then(res => res.json())
            .then(obj => {
              jsonToTable(valueDiv, obj)
              button.innerText = 'Cкрыть'
              button.style.backgroundColor = "SteelBlue"
              button.onclick = () => buttonHidetext(button, valueDiv) //вешаем на кнопку, изменяемый при каждом нажатии, онклик скрывающий или отображающий контент внутри ячейки
            })
        }
      } else if (Array.isArray(jsonObj[key])) {

        for (arrayItem of jsonObj[key]) {
          console.log(arrayItem)
          if (regexp.test(arrayItem) && typeof arrayItem === "string") {
            //если значение ссылка и строка

            const valueDiv = document.createElement('div') //div контейнер внутри ячейки
            tdValue.append(valueDiv)

            const button = document.createElement('button') // если да то создаём кнопку, текст изначально скрыт
            tdValue.append(button)
            button.innerText = 'Показать'

            //при первом нажатии получаем данные по ссылке, выводим в valueDiv

            button.onclick = () => {
              fetch(arrayItem)
                .then(res => res.json())
                .then(obj => {
                  jsonToTable(valueDiv, obj)
                  button.innerText = 'Cкрыть'
                  button.style.backgroundColor = "SteelBlue"
                  button.onclick = () => buttonHidetext(button, valueDiv) //вешаем на кнопку, изменяемый при каждом нажатии, онклик скрывающий или отображающий контент внутри ячейки
                })
            }
          } else {

          }
        }
      } else {
        tdValue.innerText = jsonObj[key] //если значение не является ссылкой, запихиваем занчение в innertext 
      }
    }
  }

  fetch('https://swapi.dev/api/people/1/')
    .then(res => res.json())
    .then(jsonObj => jsonToTable(document.body, jsonObj))
}

/*race
Используя Promise.race запустите запрос на API (swapi.dev) параллельно с delay. По результату определите, что было быстрее, запрос по сети, или определенный интервал времени. Подберите параметр delay так, что бы результат был неизвестен изначально, и при многократных запусках быстрее был то delay, то myfetch. */

{

  function delay(ms) {

    return new Promise(function (resolve, reject) {
      setTimeout(() => resolve('выиграл delay'), ms)
    })
  }

  let p = Promise.race([delay(580), fetch('https://swapi.dev/api/people/1/')
  .then(res => res.json())])
  p.then((res) => console.log(res))

}

/* Promisify: confirm
Промисифицируйте confirm. Напишите функцию, которая возвращает промис, который переходит в состояние fulfilled при нажатии "OK" и реджектится при нажатии "Cancel". Функция должна принимать строку для confirm: */
{
  function confirmPromise(text) {
    return new Promise((resolve, reject) => {
      let confResult = confirm(text)
      if (confResult) resolve()
      else reject()
    })
  }

  confirmPromise('Промисы это сложно?').then(
    () => console.log('не так уже и сложно'),
    () => console.log('respect за усидчивость и внимательность')
  )
}


/*Promisify: prompt
Аналогично предыдующему заданию промисифицируйте prompt. В случае нажатия "ОК" промис резолвится и его результатом становится текст, введенный пользователем в окне prompt. В случае нажатия "Отмены" - промис реджектится. Параметром функции будет текст сообщения в prompt*/
{
  function promptPromise(text) {
    return new Promise((resolve, reject) => {
      let promptResult = prompt(text)
      if (promptResult) resolve(promptResult)
      else reject()
    })
  }

  promptPromise("Как тебя зовут?").then(name => console.log(`Тебя зовут ${name}`), () => console.log('Ну зачем морозиться, нормально же общались'))
}
/*Promisify: LoginForm
Промисифицируйте конструктор LoginForm. В промисифицированную функцию передается DOM-элемент - родитель для формы, В колбэке, предназначенном для получения логина и пароля в момент нажатия кнопки "Login...", который вы назначаете в объекте LoginForm, зарезолвите промис. Результатом промиса должен быть объект с ключами login и password, ключи должны содержать значения полей ввода.*/

{
  function loginPromise(parent){
    function executor(resolve, reject){
        const form = new LoginForm(parent, false)
        form.inputButtonOnclick = function () {
          //console.log({login: this.getLogin(), password: this.getPass()})
          resolve({login: this.getLogin(), password: this.getPass()})
        }
    }
    
    return new Promise(executor)
}


loginPromise(document.body).then(({login, password}) => console.log(`Вы ввели ${login} и ${password}`))



  function LoginForm(parent, passOpenDefault = open){
      function Password(parent, open) {

          const inputPass = document.createElement('input')
          parent.append(inputPass)
          const checkboxPass = document.createElement('input')
          checkboxPass.type = 'checkbox'
          parent.append(checkboxPass)
          
          this.setValue = (value) => {
              inputPass.value = value
              if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк
          }      //задает значение
          this.getValue = () => inputPass.value                   //читает значение
          this.setOpen = (open) => {
              if (open) {
                  checkboxPass.checked = true
                  inputPass.type = "text"
              }
              if (!open) {
                  checkboxPass.checked = false
                  inputPass.type = "password"
              }
              if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля
          } //задает открытость текста в поле ввода
          this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода
  
          this.setOpen(open)
          inputPass.oninput = () => this.setValue(this.getValue())
          checkboxPass.oninput = () => this.setOpen(this.getOpen())
  
      }
  
      const LoginForm = document.createElement('div')
      parent.append(LoginForm)
  
      const inputLogin = document.createElement('input')
      LoginForm.append(inputLogin)
  
      let p = new Password(LoginForm, passOpenDefault)
      
      const inputButton = document.createElement('input')
      inputButton.type = 'button'
      inputButton.value = 'войти'
      LoginForm.append(inputButton)
      inputButton.disabled = true
  
      p.onChange = () => checkButtonDisabled()
      inputLogin.oninput = () => checkButtonDisabled()
  
      function checkButtonDisabled () {
          if (p.getValue() && inputLogin.value) inputButton.disabled = false
          else inputButton.disabled = true
      }

      this.getLogin = () => inputLogin.value
      this.setLogin = (value) => {
          inputLogin.value = value
          checkButtonDisabled()

      }
      this.getPass = () => p.getValue()
      this.setPass = (value) => {
          p.setValue(value)
          checkButtonDisabled()
      }
      
      inputButton.onclick = () => {
      if (typeof this.inputButtonOnclick === 'function') this.inputButtonOnclick() //функция при нажатии на кнопку войти
      }
  }


}