<html>

<head>
    <title>GQL</title>
    <meta charset='utf8' />
    <!--<style>
            #mainContainer {
                display: flex;
            }
            #aside {
                width: 30%;
            }
            #aside > a{
                display: block;
            }
            header {
                min-height: 100px;
                background-color: #AAA;
            }
        -->
    </style>
</head>

<body>
    <header>
        <div id='cartIcon'></div>
    </header>
    <div id='mainContainer'>
        <aside id='aside'>
            Категории
            Сюда надо воткнуть список корневых категорий интернет-магазина
            <a href="#/people/1">Luke</a>
            <a href="#/people/2">C-3PO</a>
            <a href="#/people/3">R2-D2</a>
            <a href="#/people/4">Dart Vader</a>

            <a href="#/films/4">new hope</a>
            <a href="#/films/5">пятая часть</a>
            <a href="#/films/3">шестая часть</a>
        </aside>
        <main id='main'>
            Контент
        </main>
    </div>
    <script>
        function createStore(reducer) {
            let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
            let cbs = []                     //массив подписчиков

            const getState = () => state            //функция, возвращающая переменную из замыкания
            const subscribe = cb => (cbs.push(cb),   //запоминаем подписчиков в массиве
                () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка

            const dispatch = action => {
                if (typeof action === 'function') { //если action - не объект, а функция
                    return action(dispatch, getState) //запускаем эту функцию и даем ей dispatch и getState для работы
                }
                const newState = reducer(state, action) //пробуем запустить редьюсер
                if (newState !== state) { //проверяем, смог ли редьюсер обработать action
                    state = newState //если смог, то обновляем state 
                    for (let cb of cbs) cb(state) //и запускаем подписчиков
                }
            }

            return {
                getState, //добавление функции getState в результирующий объект
                dispatch,
                subscribe //добавление subscribe в объект
            }
        }

        function combineReducers(reducers) {
            function totalReducer(state = {}, action) {
                const newTotalState = {}
                for (const [reducerName, reducer] of Object.entries(reducers)) {
                    const newSubState = reducer(state[reducerName], action)
                    if (newSubState !== state[reducerName]) {
                        newTotalState[reducerName] = newSubState
                    }
                }
                if (Object.keys(newTotalState).length) {
                    return { ...state, ...newTotalState }
                }
                return state
            }

            return totalReducer
        }

        const reducers = {
            promise: promiseReducer, //допилить много имен для многих промисо
            //auth: authReducer,     //часть предыдущего ДЗ
            //cart: cartReducer,     //часть предыдущего ДЗ
        }

        const totalReducer = combineReducers(reducers)
        function promiseReducer(state = {}, { type, status, payload, error }) {
            if (type === 'PROMISE') {
                //имена добавить
                return { status, payload, error }
            }
            return state
        }
        //имена добавить
        const actionPending = () => ({ type: 'PROMISE', status: 'PENDING' })
        const actionFulfilled = payload => ({ type: 'PROMISE', status: 'FULFILLED', payload })
        const actionRejected = error => ({ type: 'PROMISE', status: 'REJECTED', error })

        //имена добавить
        const actionPromise = promise =>
            async dispatch => {
                dispatch(actionPending()) //сигнализируем redux, что промис начался
                try {
                    const payload = await promise //ожидаем промиса
                    dispatch(actionFulfilled(payload)) //сигнализируем redux, что промис успешно выполнен
                    return payload //в месте запуска store.dispatch с этим thunk можно так же получить результат промиса
                }
                catch (error) {
                    dispatch(actionRejected(error)) //в случае ошибки - сигнализируем redux, что промис несложился
                }
            }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        const store = createStore(totalReducer) //не забудьте combineReducers если он у вас уже есть
        store.subscribe(() => console.log(store.getState()))

        const drawPeople = (state) => {
            const [, route] = location.hash.split('/')
            if (route !== 'people') return

            const { status, payload, error } = store.getState().promise//.имя другое
            if (status === 'PENDING') {
                main.innerHTML = `<img src='https://cdn.dribbble.com/users/63485/screenshots/1309731/infinite-gif-preloader.gif' />`
            }
            if (status === 'FULFILLED') {
                const { name, mass, eye_color, films } = payload
                main.innerHTML = `<h1>${name}</h1>
                         <section>ЖЫРНОСТЬ: ${mass}кг</section>
                         <section style="color: ${eye_color}">Цвет глаз</section>
                         `
                for (const filmUrl of films) {
                    const filmId = filmUrl.split('/films/')[1].slice(0, -1)
                    main.innerHTML += `<a href="#/films/${filmId}">Фильм №${filmId}</a>`
                }
            }
        }

        store.subscribe(drawPeople)

        store.subscribe(() => {
            const [, route] = location.hash.split('/')
            if (route !== 'films') return

            const { status, payload, error } = store.getState().promise//.имя одно
            if (status === 'PENDING') {
                main.innerHTML = `<img src='https://cdn.dribbble.com/users/63485/screenshots/1309731/infinite-gif-preloader.gif' />`
            }
            if (status === 'FULFILLED') {
                const { title, opening_crawl, characters } = payload
                main.innerHTML = `<h1>${title}</h1>
                         <p>${opening_crawl}</p>
                         `
                for (const peopleUrl of characters) {
                    const peopleId = peopleUrl.split('/people/')[1].slice(0, -1)
                    main.innerHTML += `<a href="#/people/${peopleId}">Герой №${peopleId}</a>`
                }
            }
        })

        const actionGetPeople = id =>  //имя другое
            actionPromise(fetch(`https://swapi.dev/api/people/${id}`).then(res => res.json()))

        const actionGetFilm = id =>
            actionPromise(fetch(`https://swapi.dev/api/films/${id}`).then(res => res.json()))

        const actionSomePeople = () =>
            actionPromise(fetch(`https://swapi.dev/api/people/`).then(res => res.json()))

        store.dispatch(actionSomePeople())

        store.subscribe(() => {
            const { status, payload, error } = store.getState().promise//.имя третье
            if (status === 'FULFILLED' && payload.results) {
                aside.innerHTML = ''
                for (const { url: peopleUrl, name } of payload.results) {
                    const peopleId = peopleUrl.split('/people/')[1].slice(0, -1)
                    aside.innerHTML += `<a href="#/people/${peopleId}">${name}</a>`
                }
            }
        })

        window.onhashchange = () => {
            const [, route, _id] = location.hash.split('/')

            const routes = {
                people() {
                    console.log('People', _id)
                    store.dispatch(actionGetPeople(_id))
                },
                films() {
                    store.dispatch(actionGetFilm(_id))
                },
                //category() {
                //store.dispatch(actionCategoryById(_id))
                //},
                //good(){
                ////тут был store.dispatch goodById
                //console.log('good', _id)
                //},
                login() {
                    console.log('А ТУТ ЩА ДОЛЖНА БЫТЬ ФОРМА ЛОГИНА')
                    //нарисовать форму логина, которая по нажатию кнопки Login делает store.dispatch(actionFullLogin(login, password))
                },
                //register(){
                ////нарисовать форму регистрации, которая по нажатию кнопки Login делает store.dispatch(actionFullRegister(login, password))
                //},
            }

            if (route in routes) {
                routes[route]()
            }
        }

        window.onhashchange()
    </script>
</body>

</html>