// create Store
function createStore(reducer) {
    let state = reducer(undefined, {})
    let cbs = []

    const getState = () => state
    const subscribe = cb => (cbs.push(cb),
        () => cbs = cbs.filter(c => c !== cb))

    const dispatch = action => {
        const newState = reducer(state, action)
        if (newState !== state) {
            state = newState
            for (let cb of cbs) cb()
        }
    }

    return {
        getState,
        dispatch,
        subscribe
    }
}

// create Reduser
function reducer(state, { type, ШО, СКОКА, БАБЛО, ШО_ДОБАВИТЬ, СКОКА_ДОБАВИТЬ, ЦЕНА_ДОБАВИТЬ }) {
    if (!state) {
        return {
            касса: 200,
            чай: 0,
            пиво: {
                amount: 110,
                price: 20
            },
            чипсы: {
                amount: 120,
                price: 30
            },
            сиги: {
                amount: 130,
                price: 50
            }
        }
    }

    if (type === 'КУПИТЬ' && СКОКА <= state[ШО].amount && БАБЛО === (СКОКА * state[ШО].price)) {
        return {
            ...state,
            [ШО]: {
                amount: state[ШО].amount - СКОКА,
                price: state[ШО].price
            },
            касса: state.касса + БАБЛО
        }
    }

    if (type === 'КУПИТЬ' && СКОКА <= state[ШО].amount && БАБЛО > (СКОКА * state[ШО].price)) {
        return {
            ...state,
            [ШО]: {
                amount: state[ШО].amount - СКОКА,
                price: state[ШО].price
            },
            касса: state.касса + (СКОКА * state[ШО].price),
            чай: state.чай + (БАБЛО - (СКОКА * state[ШО].price))
        }
    }

    if (type === 'ДОБАВИТЬ' && !(ШО_ДОБАВИТЬ in state) && state.касса >= (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)) {
        return {
            ...state,
            [ШО_ДОБАВИТЬ]: {
                amount: СКОКА_ДОБАВИТЬ,
                price: ЦЕНА_ДОБАВИТЬ
            },
            касса: state.касса - (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)
        }
    }

    if (type === 'ДОБАВИТЬ' && ШО_ДОБАВИТЬ in state && state.касса >= (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)) {
        return {
            ...state,
            [ШО_ДОБАВИТЬ]: {
                amount: state[ШО_ДОБАВИТЬ].amount + СКОКА_ДОБАВИТЬ,
                price: ЦЕНА_ДОБАВИТЬ
            },
            касса: state.касса - (СКОКА_ДОБАВИТЬ * ЦЕНА_ДОБАВИТЬ)
        }
    }

    return state
}
const store = createStore(reducer)

// create divStore
const divStore = document.createElement('div')
divStore.style.cssText = `
        min-width: 700px;
        width: 50%;
        border: 1px solid #A9A9A9;
        border-radius: 8px;
        box-shadow: rgb(0 0 0 / 50%) 5px 5px 5px 0px;
        padding: 20px;`
document.body.append(divStore)

// create divStore title
const divStoreitle = document.createElement('h1')
divStoreitle.innerText = 'ЛАРЕК'
divStoreitle.style.cssText = `
    text-align: center;`
divStore.append(divStoreitle)

// create Table of Store
let table, col, row

const createTable = () => {
    table = document.createElement('table')
    divStore.append(table)

    // create names of parametrs
    const params = []
    for (const child of Object.values(store.getState())) {
        for (const key of Object.keys(child)) {
            if (!params.includes(key)) {
                params.push(key);
            }
        }
    }

    // create Header of table
    row = document.createElement('tr')
    table.append(row)

    // create first cell in Header
    col = document.createElement('td')
    row.append(col)

    // create header names
    for (const key of params) {
        col = document.createElement('td')
        col.innerText = `${key}`
        col.style.cssText = `
                font-size: 1.5em;
                padding: 5px 10px;
                margin: 0 10px;
                text-align: center;
                background-color: #D9D9D9;`
        row.append(col)
    }

    // create table body

    for (const [key, values] of Object.entries(store.getState())) {

        if (key === 'касса') {
            row = document.createElement('tr')
            table.append(row)

            col = document.createElement('td')
            col.innerText = `${key.toUpperCase()}`
            col.style.cssText = `
                min-width: 150px;
                font-size: 2em;
                padding: 5px 10px;
                text-align: left`
            row.append(col)

            col = document.createElement('td')
            col.innerText = `${values}`
            col.style.cssText = `
                font-size: 2em;
                text-align: center;`
            row.append(col)
        } else if (key === 'чай') {
            row = document.createElement('tr')
            table.append(row)

            col = document.createElement('td')
            col.innerText = `На ${key.toUpperCase()} редюсеру-трудяге`
            col.style.cssText = `
                min-width: 150px;
                font-size: 1.5em;
                padding: 5px 10px;
                text-align: left`
            row.append(col)

            col = document.createElement('td')
            col.innerText = `${values}`
            col.style.cssText = `
                font-size: 1.5em;
                text-align: center;`
            row.append(col)
        } else {
            // рисуем строку заголовков
            row = document.createElement('tr')
            table.append(row)

            col = document.createElement('td')
            col.innerText = `${key.toUpperCase()}`
            col.style.cssText = `
                min-width: 150px;
                font-size: 2em;
                padding: 5px 10px;
                text-align: left`
            row.append(col)

            // рисуем строки значений для товаров
            for (const name of params) {
                col = document.createElement('td')
                col.innerText = `${(Object.keys(values)).includes(name) ? values[name] : ''}`
                col.style.cssText = `
                    font-size: 1.5em;
                    text-align: center`
                row.append(col)
            }
        }
    }
    return table
}
createTable()

// start test in console.log
store.subscribe(() => console.log(store.getState()))

// create divWindow
const divWindow = document.createElement('div')
divWindow.style.cssText = `
    min-width: 700px;
    width: 50%;
    padding: 10px;
    margin-top: 30px;`
document.body.append(divWindow)

// create divWindow title
const divWindowitle = document.createElement('h2')
divWindowitle.innerText = 'Покупка в ларьке'
divWindowitle.style.cssText = `
    text-align: center;`
divWindow.append(divWindowitle)


// create inputAmount
const inputAmount = document.createElement('input')
inputAmount.type = 'number'
inputAmount.min = 0
inputAmount.placeholder = 'Количество товара'
divWindow.append(inputAmount)

// ceate inputMoney
const inputMoney = document.createElement('input')
inputMoney.type = 'number'
inputMoney.min = 0
inputMoney.placeholder = 'Сумма, которую отдаете'
divWindow.append(inputMoney)

let selectProduct
createListProduct = () => {
    // create selectProduct
    selectProduct = document.createElement('select')
    divWindow.insertBefore(selectProduct, inputMoney)

    for (let key of Object.keys(store.getState())) {
        if (key !== 'касса' && key !== 'чай') {
            let optionInput = document.createElement('option')
            optionInput.innerText = `${key}`
            selectProduct.append(optionInput)
        }
    }
    return selectProduct
}
createListProduct()

// create buyButton 
const buyButton = document.createElement('button')
buyButton.innerText = 'Купить'
divWindow.append(buyButton)

// create add div
const divAdd = document.createElement('div')
divAdd.style.cssText = `
        min-width: 700px;
        width: 50%;
        margin-top: 40px;`
document.body.append(divAdd)

// create add div title
const divAddTitle = document.createElement('h2')
divAddTitle.innerText = 'Пополнение ларька'
divAddTitle.style.cssText = `
    text-align: center;`
divAdd.append(divAddTitle)

// create inputAddProduct
const inputAddProduct = document.createElement('input')
inputAddProduct.type = 'text'
inputAddProduct.placeholder = 'Введите имя продукта'
divAdd.append(inputAddProduct)

// create inputAddAmount
const inputAddAmount = document.createElement('input')
inputAddAmount.type = 'number'
inputAddAmount.min = 0
inputAddAmount.placeholder = 'Введите количество продукта'
divAdd.append(inputAddAmount)

// create inputAddPrice
const inputAddPrice = document.createElement('input')
inputAddPrice.type = 'number'
inputAddPrice.min = 0
inputAddPrice.placeholder = 'Введите цену продукта'
divAdd.append(inputAddPrice)

// create addProductButton
const addProductButton = document.createElement('button')
addProductButton.innerText = 'Добавить продукт'
divAdd.append(addProductButton)

// mistake alert
addProductButton.onclick = () => {
    if ((+inputAddAmount.value * +inputAddPrice.value) > store.getState().касса) {
        alert('В кассе нет столько денег! Давай торговаться?')
    }
}

// start addProductButton
addProductButton.addEventListener('click', () => store.dispatch({ type: 'ДОБАВИТЬ', ШО_ДОБАВИТЬ: inputAddProduct.value, СКОКА_ДОБАВИТЬ: +inputAddAmount.value, ЦЕНА_ДОБАВИТЬ: +inputAddPrice.value }))

// mistake alert
buyButton.onclick = () => {
    if (+inputAmount.value > store.getState()[selectProduct.value].amount) {
        alert(`Количество товара, который вы хотите купить, больше, чем наличие на складе! На складе ${store.getState()[selectProduct.value].amount} единиц ${selectProduct.value}`)
    } else if (+inputMoney.value < (+inputAmount.value * store.getState()[selectProduct.value].price)) {
        alert(`Вы даете ${inputMoney.value}. А нужно ${+inputAmount.value * store.getState()[selectProduct.value].price}. Добавьте ${(+inputAmount.value * store.getState()[selectProduct.value].price) - +inputMoney.value}`)
    }
}

// start buyButton
buyButton.addEventListener('click', () => store.dispatch({ type: 'КУПИТЬ', ШО: selectProduct.value, СКОКА: +inputAmount.value, БАБЛО: +inputMoney.value }))

// Relaod table with new datas
store.subscribe(() => {
    table.remove(),
        selectProduct.remove(),
        createTable(),
        createListProduct()

})