//debugger;
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 => { 
      const newState = reducer(state, action) //пробуем запустить редьюсер
      if (newState !== state){ //проверяем, смог ли редьюсер обработать action
          state = newState //если смог, то обновляем state 
          for (let cb of cbs)  cb() //и запускаем подписчиков
      }
  }
  
  return {
      getState, //добавление функции getState в результирующий объект
      dispatch,
      subscribe //добавление subscribe в объект
  }
}

function reducer(state, {type, ШО, СКОКА, БАБЛО}){ //объект action деструктуризируется на три переменных
  if (!state){ //начальная уборка в ларьке:
      return {
          пиво: {count: 100, price: 30},
          чипсы:{count: 100, price: 25},
          сиги: {count: 100, price: 35},
          касса:{count: 0, change: 0},                              //            касса: 0, при покупках увеличивается
      }
  }
  if (type === 'КУПИТЬ'){ //если тип action - КУПИТЬ, то:
      //проверить на:
      //наличие товара как такового (есть ли ключ в объекте)
      //количество денег в action
      //наличие нужного количества товара.
      //и только при соблюдении этих условий обновлять state. 
      if((state[ШО]['count'] - СКОКА)  < 0 ) {
        const div = document.getElementById('message');
        div.innerText = `столько ${ШО} нет в наличии, есть ${state[ШО]['count']}`;
        setTimeout( () => div.innerText = '', 2500);
        return state;
      }

      if ((БАБЛО - СКОКА* state[ШО]['price']) < 0) {
        const div = document.getElementById('message');
        div.innerText = `надо добавитть ${СКОКА * state[ШО]['price'] - БАБЛО} грн.`;
        setTimeout( () => div.innerText = '', 2500);
        return state;
      }

      if (state[ШО]) {
        return {
          ...state, //берем все что было из ассортимента
          [ШО]: {
            ...state[ШО],
            count: state[ШО]['count'] - СКОКА,
          } ,
          ['касса']: {
            ...state['касса'],
            count: state['касса']['count'] + (СКОКА * state[ШО]['price']),
            change: БАБЛО -  СКОКА * state[ШО]['price'],   
          }                         //и уменьшаем то, что покупается на количество
        }
      }  
  }


  return state //если мы не поняли, что от нас просят в `action` - оставляем все как есть
}

const store = createStore(reducer); 

for (let [key, value] of Object.entries(store.getState())) {
  if(key === 'касса') {
    continue;
  }
  let option = document.createElement('option');
  option.innerHTML = `${key}`;
  goods.append(option);

}

function viewStore () {
  const table = document.createElement('table');
  table.id = 'table';
  document.body.prepend(table);
  const tr = document.createElement('tr');
  table.append(tr);
  const th1 = document.createElement('th');
  th1.innerText = 'Товар';
  tr.append(th1);
  const th2 = document.createElement('th');
  th2.innerText = 'Количество товара';
  tr.append(th2);
  const th3 = document.createElement('th');
  th3.innerText = 'Цена';
  tr.append(th3);

  for (let [key, value] of Object.entries(store.getState())) {
   
    const tr = document.createElement('tr');
    const th = document.createElement('th');
    th.style.width = '150px';
    table.append(tr);
    tr.appendChild(th).innerHTML = `${key}`;

    for (let [key1, value1] of Object.entries(value)) {

      const td = document.createElement('td');
      td.style.width = '70px';
      tr.appendChild(td).innerHTML =`${value1}`;
    }
  }
}
viewStore();

function deleteTable () {
  const table = document.getElementById('table');
  table.remove();
}

store.subscribe(deleteTable);
store.subscribe(viewStore);
//надо бы напилить цикл, который в select напихивает ассортимент. 
//возможно, если вы собираетесь выводить (и обновлять) количество,
//это надо делать где в subscribe, иначе оно не будет обновлять количество

const купи = (ШО, СКОКА, БАБЛО) => ({type: 'КУПИТЬ', ШО, СКОКА, БАБЛО});

buy.onclick = () => { 
  let select = document.getElementById('goods');
  let valueSelect = select.options[select.selectedIndex].text;
  let input = document.getElementById('quantity');
  let valueInput = input.value;
  let cash = document.getElementById('cash').value;

  store.dispatch({type:'КУПИТЬ', ШО: `${valueSelect}`, СКОКА: `${valueInput}`, БАБЛО: `${cash}`});
  setTimeout(() => document.getElementById('quantity').value = '', 2500);
  setTimeout(() => document.getElementById('cash').value = '', 2500);
};

  
//достает выбранный товар и количество из DOM +
//    store.dispatch(купи(....,....)) +
//запомнит функцию во внутреннем массиве cbs. 
//она будет запущена при любом успешном dispatch 
const unsubscribe = store.subscribe(() => console.log(store.getState())) 

//setTimeout(unsubscribe, 10000) //отпишемся через 10 секунд, например

//происходит запуск редьюсера, который создает новый state. 
//dispatch запускает всех подписчиков из массива cbs

// function smth(){
//   const h1 = document.createElement('h1')
//   shop.append(h1)
//   store.subscribe(() => h1.innerText = store.getState().пиво)
//   h1.innerText = store.getState().пиво
// }
// smth()
// smth()

//setTimeout(() => store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3}), 5000)