import { useCallback, useEffect, useReducer } from 'react';

import BlogPosts from './components/BlogPosts';

const initialHttpState = {
  data: null,
  isLoading: false,
  error: null,
};

function httpReducer(state, action) {
  if (action.type === 'FETCH_START') {
    return {
      ...state, // Kopiowanie istniejącego stanu.
      isLoading: state.data ? false : true,
      error: null,
    };
  }

  if (action.type === 'FETCH_ERROR') {
    return {
      data: null,
      isLoading: false,
      error: action.payload,
    };
  }

  if (action.type === 'FETCH_SUCCESS') {
    return {
      data: action.payload,
      isLoading: false,
      error: null,
    };
  }

  return initialHttpState; // Wartość domyślna stosowana dla nieznanych operacji.
}

function App() {
  const [httpState, dispatch] = useReducer(httpReducer, initialHttpState);

  // Używanie useCallback(), aby zapobiec pętli nieskończonej w useEffect().
  const fetchPosts = useCallback(async function fetchPosts() {
    dispatch({ type: 'FETCH_START' });

    try {
      const response = await fetch(
        'https://jsonplaceholder.typicode.com/posts'
      );

      if (!response.ok) {
        throw new Error('Pobieranie artykułów zakończone niepowodzeniem.');
      }

      const posts = await response.json();

      dispatch({ type: 'FETCH_SUCCESS', payload: posts });
    } catch (error) {
      dispatch({ type: 'FETCH_ERROR', payload: error.message });
    }
  }, []);

  useEffect(
    function () {
      fetchPosts();
    },
    [fetchPosts]
  );

  return (
    <>
      <header>
        <h1>Blog ze złożonym stanem</h1>
        <button onClick={fetchPosts}>Wczytaj artykuły</button>
      </header>
      {httpState.isLoading && <p>Wczytywanie w toku...</p>}
      {httpState.error && <p>{httpState.error}</p>}
      {httpState.data && <BlogPosts posts={httpState.data} />}
    </>
  );
}

export default App;
