import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState, AppThunk } from '../../app/store';

import { fetchLink } from './${featureNameLowercase}API';

export interface ${featureNameLowercase}State {
  status: 'idle' | 'fetching' | 'failed';
}

const initialState: ${featureNameLowercase}State = {
  status: 'idle',
};

// The function below is called a thunk and allows us to perform async logic. It
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
// will call the thunk with the `dispatch` function as the first argument. Async
// code can then be executed and other actions can be dispatched. Thunks are
// typically used to make async requests.
export const fetchLinkAsync = createAsyncThunk(
  '${featureNameLowercase}/fetchLink',
  async (link: string) => {
    const response = await fetchLink(link);
    return response;
  }
);

export const ${featureNameLowercase}Slice = createSlice({
  name: '${featureNameLowercase}',
  initialState,
  // The `reducers` field lets us define reducers and generate associated actions
  reducers: {
    updateState: (state, action: PayloadAction<'idle' | 'fetching' | 'failed'>) => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.status = action.payload
    },
  },
  // The `extraReducers` field lets the slice handle actions defined elsewhere,
  // including actions generated by createAsyncThunk or in other slices.
  extraReducers: (builder) => {
    builder
      .addCase(fetchLinkAsync.pending, (state) => {
        state.status = 'fetching';
      })
      .addCase(fetchLinkAsync.fulfilled, (state) => {
        state.status = 'idle';
      })
      .addCase(fetchLinkAsync.rejected, (state, action) => {
        console.log(action.payload);
        state.status = 'failed';
      });
  },
});

export const { updateState } = ${featureNameLowercase}Slice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`
export const selectStatus = (state: RootState) => state.${featureNameLowercase}.status;


export default ${featureNameLowercase}Slice.reducer;
