// Материал
// Изучите все примеры кода из материала занятия, используя отладку в Developer Tools
{
    // done
}



// Arrow to Functions
// Переведите любые пять заданий из предыдущего ДЗ по функциям в синтаксис function
{
    {
        //     const string = (str) => str.split('\\n').join('\n')
        //     alert(string(prompt('Введите в поле ниже любую строку. Для перехода на новую строку используйте комбинацию: \n')))

        //  аналог в function

        const string = function () {
            let str = prompt('Введите в поле ниже любую строку. Для перехода на новую строку используйте комбинацию: "\\n"')

            return alert(str.split('\\n').join('\n'))
        }
        string()
    }

    {
        // const age = (insertData, defaultValue) => insertData !== null && insertData !== '' ? `Вы родились в ${2022 - +insertData} году` : defaultValue
        // alert(age(prompt('Укажите в поле, сколько вам полных лет (цифрами):'), 'Вы не ввели ваш возраст!'))

        //  аналог в function

        const age = function (insertData, defaultValue) {
            let result = insertData !== null && insertData !== '' ? `Вы родились в ${2022 - +insertData} году` : defaultValue

            return alert(result)
        }
        age(prompt('Укажите в поле, сколько вам полных лет (цифрами):'), 'Вы не ввели ваш возраст!')
    }

    {
        // const autorization = (login, pass) => login === 'admin' && pass === 'qwerty'
        // autorization(prompt('Введите в поле ниже логин'), prompt('Введите пароль в поле нижне'))

        //  аналог в function

        const autorization = function (login, pass) {
            let result = login === 'admin' && pass === 'qwerty'

            return alert(result)
        }
        autorization(prompt('Введите в поле ниже логин'), prompt('Введите пароль в поле нижне'))
    }

    {
        // const string = 'Скоро бляха зима, ни одна муха на улицу не вылетит. Пляха - это шото, а шабля - это мощное оружие'
        // const badWords = ['бляха', 'муха', "пляха", "шабля"]

        // const checkString = (str, badArr) => {
        //     const result = str.toLowerCase().split(' ').filter(x => !badArr.includes(x) ? x : '')
        //     return result.join(' ')
        // }

        // checkString(string, badWords)

        //  аналог в function

        const string = 'Скоро бляха зима, ни одна муха на улицу не вылетит. Пляха - это шото, а шабля - это мощное оружие'
        const badWords = ['бляха', 'муха', "пляха", "шабля"]

        const checkString = function (str, badArr) {
            let result = str.toLowerCase().split(' ').filter(x => !badArr.includes(x) ? x : '')

            return result.join(' ')
        }
        checkString(string, badWords)
    }

    {
        // const colorConverter = ([red, green, blue]) => alert('Указанный Вами цвет для CSS: #' +
        //     ((+red) > 255 ? alert('Слишком большая цифра') : ((+red) < 16 ? + '0' + (+red).toString(16).toUpperCase() : (+red).toString(16).toUpperCase())) +
        //     ((+green) > 255 ? alert('Слишком большая цифра') : ((+green) < 16 ? + '0' + (+green).toString(16).toUpperCase() : (+green).toString(16).toUpperCase())) +
        //     ((+blue) > 255 ? alert('Слишком большая цифра') : ((+blue) < 16 ? + '0' + (+blue).toString(16).toUpperCase() : (+blue).toString(16).toUpperCase())))

        // colorConverter(['Введите целое число 0 ... 255 для красного цвета', 'Введите целое число 0 ... 255 для зеленого цвета', 'Введите целое число 0 ... 255 для синего цвета'].map(prompt))

        //  аналог в function
        const colorConverter = function ([red, green, blue]) {
            let result = 'Указанный Вами цвет для CSS: #' +
                ((+red) > 255 ? alert('Слишком большая цифра') : ((+red) < 16 ? + '0' + (+red).toString(16).toUpperCase() : (+red).toString(16).toUpperCase())) +
                ((+green) > 255 ? alert('Слишком большая цифра') : ((+green) < 16 ? + '0' + (+green).toString(16).toUpperCase() : (+green).toString(16).toUpperCase())) +
                ((+blue) > 255 ? alert('Слишком большая цифра') : ((+blue) < 16 ? + '0' + (+blue).toString(16).toUpperCase() : (+blue).toString(16).toUpperCase()))

            return alert(result)
        }
        colorConverter(['Введите целое число 0 ... 255 для красного цвета', 'Введите целое число 0 ... 255 для зеленого цвета', 'Введите целое число 0 ... 255 для синего цвета'].map(prompt))
    }

}



// createPerson
// Создайте функцию createPerson, которая принимает два параметра: name и surname, и возвращает объект с ключами name, surname, getFullName.getFullName должна быть функцией, которая работает с объектом через this, а так же готова к тому, что в объекте в последствии добавить ключ fatherName
{
    const a = createPerson("Вася", "Пупкин")
    const b = createPerson("Анна", "Иванова")
    const c = createPerson("Елизавета", "Петрова")

    function createPerson(name, surName) {
        let person = {
            name: `${name}`,
            surname: `${surName}`,
            getFullName: function getFullName() {
                return `${this.name} ${this.fatherName || ''} ${this.surname}`
            }
        }

        return person
    }

    console.log(a.getFullName()) //Вася Пупкин

    a.fatherName = 'Иванович'    //Вася Иванович Пупкин
    console.log(a.getFullName())

    console.log(b.getFullName())

    console.log(c.name)//Анна Иванова
}



// createPersonClosure
// Задание в целом, аналогично предыдущему, однако, в объект заносить name, surname, fatherName и age не нужно.name и surname должны быть параметрами, переменные age и fatherName объявите через let в теле createPersonClosure.В нутри createPersonClosure объявите следующие функции:
//      getName
//      getSurname
//      getFatherName
//      getAge
//      getFullName
// Эти функции должны возвращать переменные, объявленные в функции createPersonClosure

// Следующие функции:
//      setName
//      setSurname
//      setFatherName
//      setAge
//      setFullName
// должны принимать один параметр(newName, newSurname и т.п.), проверять его на корректность и менять значение переменных, объявленных внутри createPersonClosure.

// Проверки на корректность:
//      имя, фамилия, отчество должно быть строкой с большой буквы
//      возраст должен быть числом от 0 до 100.
// Если проверка на корректность не пройдена, функция не должна менять соответстующую переменную.

// Функция setFullName должна разбивать строку по пробелам и заносить части строки в surname, name и fatherName

// Все функции set должны возвращать то значение, которое по итогу попало во внутренюю переменную.То есть если новое значение некорректно, то функция возвращает старое значение
// В объекте - результате createPersonClosure должны быть только эти 10 функций(геттеров и сеттеров).В коде функций this не используется
{
    const a = createPersonClosure("Вася", "Пупкин")
    const b = createPersonClosure("Анна", "Иванова")

    function createPersonClosure(name, surName) {
        let fatherName, age

        return person = {
            getName() {
                return name
            },
            getSurname() {
                return surName
            },
            getFatherName() {
                return fatherName
            },
            getAge() {
                return age
            },
            getFullName() {
                return `${name} ${fatherName} ${surName}`
            },

            setName(newName) {
                if (newName[0] === newName[0].toUpperCase()) {
                    name = newName
                }
                return name
            },
            setSurname(newSurname) {
                if (newSurname[0] === newSurname[0].toUpperCase()) {
                    surName = newSurname
                }
                return surName
            },
            setFatherName(newFatherName) {
                if (newFatherName[0] === newFatherName[0].toUpperCase()) {
                    fatherName = newFatherName
                }
                return fatherName
            },
            setAge(newAge) {
                if (newAge >= 0 && newAge <= 100) {
                    age = newAge
                }
                return age
            },
            setFullName(newFullName) {
                name = newFullName.split(' ')[1] || ''
                surName = newFullName.split(' ')[0] || ''
                fatherName = newFullName.split(' ')[2] || ''
                return `${name} ${fatherName} ${surName}`
            }
        }
    }

    console.log(person)

    console.log(a.getName())

    a.setAge(15)
    console.log(a.getAge())

    a.setAge(150) //не работает
    console.log(a.getAge())

    b.setFullName("Петрова Анна Николаевна")
    console.log(b.getFatherName()) //Николаевна
}



// createPersonClosureDestruct
// Сделайте набор параметров функции из предыдущего задания объектом, используйте деструктуризацию для извлечения параметров.
// Задайте значения по умолчанию
{
    const a = createPersonClosureDestruct(createPerson("Вася Пупкин"))
    const b = createPersonClosureDestruct({ name: 'Николай', age: 75 })

    // Функция для "Вася Пупкин"
    function createPerson(string) {
        let personString = {
            name: string.split(' ')[0],
            surName: string.split(' ')[1]
        }

        return personString
    }

    // функция основная
    function createPersonClosureDestruct(personString) {
        let { name = 'Anon', surName = 'Anonov', fatherName = 'Anonovich', age = 'Unsettled' } = personString
        return person = {
            getName() {
                return name
            },
            getSurname() {
                return surName
            },
            getFatherName() {
                return fatherName
            },
            getAge() {
                return age
            },
            getFullName() {
                return `${name} ${fatherName} ${surName}`
            },

            setName(newName) {
                if (newName[0] === newName[0].toUpperCase()) {
                    name = newName
                }
                return name
            },
            setSurname(newSurname) {
                if (newSurname[0] === newSurname[0].toUpperCase()) {
                    surName = newSurname
                }
                return surName
            },
            setFatherName(newFatherName) {
                if (newFatherName[0] === newFatherName[0].toUpperCase()) {
                    fatherName = newFatherName
                }
                return fatherName
            },
            setAge(newAge) {
                if (newAge >= 0 && newAge <= 100) {
                    age = newAge
                }
                return age
            },
            setFullName(newFullName) {
                name = newFullName.split(' ')[1] || ''
                surName = newFullName.split(' ')[0] || ''
                fatherName = newFullName.split(' ')[2] || ''
                return `${name} ${fatherName} ${surName}`
            }
        }
    }

    console.log(person)

    console.log(a.getName())
    console.log(a.getSurname())

    console.log(b.getName())
    console.log(b.getAge())

    console.log(a.getAge())
    a.setAge(30)
    console.log(a.getAge())

    console.log(b.getFullName())
}


// isSorted
// Напишите функцию isSorted, которая принимает набор параметров любого размера, и возвращает true, когда все параметры - это числа, и каждое из них больше предыдущего параметр
{
    function isSort(...params) {
        let result = true
        for (let i = 0; i < params.length; i++) {
            if (typeof params[i] !== 'number' || isNaN(params[i]) || params[i] > params[i + 1]) {
                result = false
            }
        }

        return console.log('Correct? ', result)
    }

    console.log(isSort(1, 2, 3, 4, 5, 6))
    console.log(isSort(1, 2, 3, 4, 6, 4))
    console.log(isSort(1, 2, [], 4, 5))
    console.log(isSort(1, 2, 'test', 4, 5))
    console.log(isSort(1, 2, NaN, 4, 5))
    console.log(isSort(true, 2, 3, 4, 5))
}



// Test isSorted
// Используя циклический ввод в массив(задание array fill), обеспечьте ввод данных для isSorted
{
    function isSort() {
        const params = []
        let item, result = true

        while (item !== null && item !== '') {
            item = prompt('введи что-то для добавления в массив')
            if (item !== null && item !== '') { params.push(+item) }
            else break
        }

        for (let i = 0; i < params.length; i++) {
            if (typeof params[i] !== 'number' || isNaN(params[i]) || params[i] > params[i + 1]) {
                result = false
            }
        }

        return console.log('Correct?: ', result)
    }

    console.log(isSort())
}



// personForm
// Напишите функцию, которая принимает два параметра: родительский DOM - элемент и объект - результат работы createPersonClosure(или createPersonClosureDestruct, результаты у обоих этих функций одинаковые) и рисует форму, которая позволяет редактировать данные о персоне.
// В начале работы personForm создает 5 полей ввода(имя, фамилия, отчество, возраст, ФИО) в родительском DOM - элементе и устанавливает туда значения, прочитанные с помощью getName, getSurname и т.д.
// По событию oninput в любом из полей ввода нужно запускать соответствующий set..... Например при изменении поля ввода имени должен запускаться setName(какой - то инпут.value).Функции set... возвращают значение, и его нужно занести обратно в input.Таким образом в полях ввода невозможно будет ввести некорректные значения(например возраст не сможет выйти за пределы 0 - 100 лет)
{
    const b = createPersonClosure("Анна", "Иванова")
    b.setAge(15)
    b.setFullName("Петрова Анна Николаевна")

    // createPersonClosure
    function createPersonClosure(name, surName) {
        let fatherName, age

        return person = {
            getName() {
                return name
            },
            getSurname() {
                return surName
            },
            getFatherName() {
                return fatherName
            },
            getAge() {
                return age
            },
            getFullName() {
                return `${name} ${fatherName} ${surName}`
            },

            setName(newName) {
                if (newName[0] === newName[0].toUpperCase()) {
                    name = newName
                }
                return name
            },
            setSurname(newSurname) {
                if (newSurname[0] === newSurname[0].toUpperCase()) {
                    surName = newSurname
                }
                return surName
            },
            setFatherName(newFatherName) {
                if (newFatherName[0] === newFatherName[0].toUpperCase()) {
                    fatherName = newFatherName
                }
                return fatherName
            },
            setAge(newAge) {
                if (newAge >= 0 && newAge <= 100) {
                    age = newAge
                }
                return age
            },
            setFullName(newFullName) {
                name = newFullName.split(' ')[1] || ''
                surName = newFullName.split(' ')[0] || ''
                fatherName = newFullName.split(' ')[2] || ''
                return `${name} ${fatherName} ${surName}`
            }
        }
    }

    function personForm(parent, person) {

        //насоздавать инпутов (5 штук)
        //надобавлять их в parent
        parent = document.createElement('div')
        document.body.append(parent)

        let nameInput = document.createElement('input')
        nameInput.value = person.getName()
        parent.append(nameInput)

        let surNameInput = document.createElement('input')
        surNameInput.value = person.getSurname()
        parent.append(surNameInput)

        let fatherNameInput = document.createElement('input')
        fatherNameInput.value = person.getFatherName()
        parent.append(fatherNameInput)

        let ageInput = document.createElement('input')
        ageInput.value = person.getAge()
        parent.append(ageInput)

        let fullNameInput = document.createElement('input')
        fullNameInput.value = person.getFullName()
        parent.append(fullNameInput)

        //навесить каждому из них обработчик события типа nameInput.oninput = () => {
        //тут пытаемся менять person используя person.setName. Текст в инпуте должен стать таким, который вернет setName
        //}
        nameInput.oninput = () => {
            nameInput.value = person.setName(nameInput.value)
        }

        surNameInput.oninput = () => {
            surNameInput.value = person.setSurname(surNameInput.value)
        }

        fatherNameInput.oninput = () => {
            fatherNameInput.value = person.setFatherName(fatherNameInput.value)
        }

        ageInput.oninput = () => {
            ageInput.value = person.setAge(ageInput.value)
        }

        fullNameInput.oninput = () => {
            fullNameInput.value = person.setFullName(fullNameInput.value)
        }
    }

    personForm(document.body, b)
}



// getSetForm
// Сделайте функцию, которая решает предыдущую задачу универсально, то есть для любого объекта, в котором есть набор функций get... и set.... Кода станет меньше, гибкости больше, ведь в предыдущем задании много копипасты(x5)
{
    function getSetForm(parent, getSet) {
        const inputs = {} //реестр

        const updateInputs = () => {
            for (const fieldName in inputs) {
                const getKey = `get` + fieldName
                if (getKey in getSet) {
                    inputs[fieldName].value = getSet[getKey]() || ''
                }
            }
        }

        for (const getSetName in getSet) {
            const getOrSet = getSetName.slice(0, 3)
            const fieldName = getSetName.slice(3)
            const setKey = `set` + fieldName
            const getKey = `get` + fieldName

            if (!(fieldName in inputs)) {
                inputs[fieldName] = document.createElement('input')
                parent.append(inputs[fieldName])
                if (!(setKey in getSet)) {
                    inputs[fieldName].disabled = true
                }

                inputs[fieldName].type = typeof getSet[getKey]()
                inputs[fieldName].placeholder = fieldName
                inputs[fieldName].oninput = () => {
                    inputs[fieldName].value = getSet[setKey](inputs[fieldName].value)
                    updateInputs()
                }
            }
        }
        updateInputs()
    }


    // проверка


    function createPersonClosure(name, surName) {
        let fatherName, age

        return person = {
            getName() {
                return name
            },
            getSurname() {
                return surName
            },
            getFatherName() {
                return fatherName
            },
            getAge() {
                return age
            },
            getFullName() {
                return `${name} ${fatherName} ${surName}`
            },

            setName(newName) {
                if (newName[0] === newName[0].toUpperCase()) {
                    name = newName
                }
                return name
            },
            setSurname(newSurname) {
                if (newSurname[0] === newSurname[0].toUpperCase()) {
                    surName = newSurname
                }
                return surName
            },
            setFatherName(newFatherName) {
                if (newFatherName[0] === newFatherName[0].toUpperCase()) {
                    fatherName = newFatherName
                }
                return fatherName
            },
            setAge(newAge) {
                if (newAge >= 0 && newAge <= 100) {
                    age = newAge
                }
                return age
            },
            setFullName(newFullName) {
                name = newFullName.split(' ')[1] || ''
                surName = newFullName.split(' ')[0] || ''
                fatherName = newFullName.split(' ')[2] || ''
                return `${name} ${fatherName} ${surName}`
            }
        }
    }



    let car;
    {
        let brand = 'BMW', model = 'X5', volume = 2.4
        car = {
            getBrand() {
                return brand
            },
            setBrand(newBrand) {
                if (newBrand && typeof newBrand === 'string') {
                    brand = newBrand
                }
                return brand
            },

            getModel() {
                return model
            },
            setModel(newModel) {
                if (newModel && typeof newModel === 'string') {
                    model = newModel
                }
                return model
            },

            getVolume() {
                return volume
            },
            setVolume(newVolume) {
                newVolume = +newVolume
                if (newVolume && newVolume > 0 && newVolume < 20) {
                    volume = newVolume
                }
                return volume
            },

            getTax() {
                return volume * 100
            }
        }
    }

    getSetForm(document.body, car)
    getSetForm(document.body, createPersonClosure('Анон', "Анонов"))
}