import type { PayloadAction } from '@reduxjs/toolkit';
import { createAppSlice } from '../../app/createAppSlice';
import type { Book, InputBook } from './Book';

export type BooksSliceState = {
  books: Book[];
  status: 'idle' | 'loading' | 'failed';
};

export const booksSlice = createAppSlice({
  name: 'books',
  initialState: { books: [], status: 'idle' } as BooksSliceState,
  reducers: (create) => ({
    remove: create.reducer((state, action: PayloadAction<number>) => {
      state.books = state.books.filter((book) => book.id !== action.payload);
    }),
    save: create.reducer((state, action: PayloadAction<InputBook>) => {
      if (action.payload.id) {
        const index = state.books.findIndex((b) => b.id === action.payload.id);
        state.books[index] = {
          ...state.books[index],
          ...action.payload,
        };
      } else {
        const newBook = {
          ...action.payload,
          id: Math.max(0, ...state.books.map((b) => b.id)) + 1,
        };
        state.books.push(newBook);
      }
    }),
    loadData: create.asyncThunk(
      async () => {
        const response = await fetch('http://localhost:3001/books');
        if (!response.ok) {
          throw new Error('Failed to load books data');
        }
        return response.json();
      },
      {
        pending: (state) => {
          state.status = 'loading';
        },
        fulfilled: (state, action) => {
          state.status = 'idle';
          state.books = action.payload;
        },
        rejected: (state) => {
          state.status = 'failed';
        },
      },
    ),
  }),
  selectors: {
    selectAllBooks: (state) => state.books,
    selectBookById: (state) => (id: number) =>
      state.books.find((b) => b.id === id),
    selectStatus: (state) => state.status,
  },
});

export const { selectAllBooks, selectBookById, selectStatus } =
  booksSlice.selectors;
export const { remove, save, loadData } = booksSlice.actions;
