import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
//import { getPeople, getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';
import { getPeopleByIds, getPersonById, acceptFriendRequest as accept } from '../../helpers/rest';

const initialState = {
  people: [],
  //prefetched: [],
  status: 'idel',
  error: null,
  hasOffset: false,
  offset: 0
}

// export const fetchPeople = createAsyncThunk(
//   'people/fetchPeople', 
//   async (options, thunkAPI) => {
//     const response = await getPeople(options)
//     return response.json()
//   }
// )

// export const preFetchPeople = createAsyncThunk(
//   'people/preFetchPeople', 
//   async (options, thunkAPI) => {
//     const response = await getPeople(options)
//     return response.json()
//   }
// )

export const fetchPeopleByIds = createAsyncThunk(
  'people/fetchPeopleByIds',
  async (options, thunkAPI) => {
    const response = await getPeopleByIds(options)
    return response.json()
  }
)

export const fetchPerson = createAsyncThunk(
  'people/fetchPerson', 
  async (options, thunkAPI) => {
    const {userId} = options
    const response = await getPersonById(userId)
    return response.json()
  }
  ,{
    condition: (options, {getState, extra}) => {
      const {people} = getState()
      const {userId} = options
      const person = people.people.find(person => person.id === userId)
      if(person && person.website){ 
        //only proceed if full data set for user has not been fetched. person.website is not included in the initial data fetching (i.e: in friends listing ).
        return false;
      }
    }
  }
)

export const acceptFriendRequest = createAsyncThunk(
  'people/acceptFriendRequest',
  async(options) => {
    const { userId, ...rest } = options
    const response = await accept(userId, rest)
    return response.json()
  }
)

export const peopleSlice = createSlice({
  name: 'people',
  initialState,
  reducers: {
    add: (state, action) => {
      state.people.push(action.payload)
    },
    resetState: (state) => {
      return { ...initialState }
    },
    // loadPrefetched: (state, action) => {
    //   if(state.prefetched.length > 0){
    //     const records = [...state.people, ...state.prefetched];
    //     state.people = records;
    //   }
    //   state.prefetched = []
    // }
  },
  extraReducers: (builder) => {
    builder
    // .addCase(fetchPeople.pending, (state, action) => {
    //   state.status = 'loading'
    // })
    // .addCase(fetchPeople.fulfilled, (state, action) => {
    //   // const records = [...state.people, ...action.payload.musicians];
    //   // state.people      = records
    //   // state.hasOffset   = !!action.payload.offset
    //   // state.offset      = action.payload.offset
    //   // state.status      = 'succeeded'
    //   //---
    //   const records = new Set([...state.people, ...action.payload.musicians]);
    //   const unique = [];
    //   records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
    //   state.people = unique
    //   state.hasOffset   = !!action.payload.offset
    //   state.offset      = action.payload.offset
    //   state.status      = 'succeeded'
    // })
    // .addCase(fetchPeople.rejected, (state, action) => {
    //   state.status = 'failed'
    //   state.error  = action.error.message
    // })
    // .addCase(preFetchPeople.pending, (state, action) => {
    //   state.status = 'loading'
    // })
    // .addCase(preFetchPeople.fulfilled, (state, action) => {
    //   // const records = [...state.prefetched, ...action.payload.musicians];
    //   // state.prefetched  = records
    //   // state.hasOffset   = !!action.payload.offset
    //   // state.offset      = action.payload.offset
    //   // state.status      = 'succeeded'
    //   //---
    //   const records = new Set([...state.prefetched, ...action.payload.musicians]);
    //   const unique = [];
    //   records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
    //   state.people = unique
    //   state.hasOffset   = !!action.payload.offset
    //   state.offset      = action.payload.offset
    //   state.status      = 'succeeded'
    // })
    // .addCase(preFetchPeople.rejected, (state, action) => {
    //   state.error  = action.error.message
    //   state.status = 'failed'
    // })
    .addCase(acceptFriendRequest.fulfilled, (state, action) => {
    })
    .addCase(fetchPerson.fulfilled, (state, action) => {
      const person = state.people.find(person => person.id === action.payload.id)
      if(person){
        const updated = {
          ...person, 
          ...action.payload
        }
        const objIndex = state.people.findIndex((p => p.id === updated.id));
        state.people[objIndex] = updated
      }else{
        state.people.push(action.payload)
      }
    })
    .addCase(fetchPeopleByIds.pending, (state, action) => {
      state.status = 'loading'
    })
    .addCase(fetchPeopleByIds.fulfilled, (state, action) => {
      const records = new Set([...state.people, ...action.payload.musicians]);
      const unique = [];
      records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
      state.people = unique
      state.status = 'succeeded'
    })
    .addCase(fetchPeopleByIds.rejected, (state, action) => {
      state.error = action.error.message
      state.status = 'failed'
    })
  }
})

export const selectPersonById = (state, userId) => state.people.find((person) => person.id === userId) 

export const { add, resetState } = peopleSlice.actions;

export default peopleSlice.reducer;