import {
  ACCOUNT_BLOCK_SUCCESS,
  ACCOUNT_MUTE_SUCCESS,
} from 'flavours/glitch/actions/accounts';
import { CONTEXT_FETCH_SUCCESS } from 'flavours/glitch/actions/statuses';
import { TIMELINE_DELETE, TIMELINE_CONTEXT_UPDATE } from 'flavours/glitch/actions/timelines';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';

const initialState = ImmutableMap({
  ancestors: ImmutableMap(),
  descendants: ImmutableMap(),
});

const normalizeContext = (state, id, ancestors, descendants) => {
  const ancestorsIds   = ImmutableList(ancestors.map(ancestor => ancestor.id));
  const descendantsIds = ImmutableList(descendants.map(descendant => descendant.id));

  return state.withMutations(map => {
    map.setIn(['ancestors', id], ancestorsIds);
    map.setIn(['descendants', id], descendantsIds);
  });
};

const deleteFromContexts = (state, id) => {
  state.getIn(['descendants', id], ImmutableList()).forEach(descendantId => {
    state = state.updateIn(['ancestors', descendantId], ImmutableList(), list => list.filterNot(itemId => itemId === id));
  });

  state.getIn(['ancestors', id], ImmutableList()).forEach(ancestorId => {
    state = state.updateIn(['descendants', ancestorId], ImmutableList(), list => list.filterNot(itemId => itemId === id));
  });

  state = state.deleteIn(['descendants', id]).deleteIn(['ancestors', id]);

  return state;
};

const filterContexts = (state, relationship) => {
  return state.map(
    statuses => statuses.filter(
      status => status.get('account') !== relationship.id));
};

const updateContext = (state, status, references) => {
  return state.update('descendants', map => {
    references.forEach(parentId => {
      map = map.update(parentId, ImmutableList(), list => {
        if (list.includes(status.id)) {
          return list;
        }

        return list.push(status.id);
      });
    });

    return map;
  });
};

export default function contexts(state = initialState, action) {
  switch(action.type) {
  case ACCOUNT_BLOCK_SUCCESS:
  case ACCOUNT_MUTE_SUCCESS:
    return filterContexts(state, action.relationship);
  case CONTEXT_FETCH_SUCCESS:
    return normalizeContext(state, action.id, action.ancestors, action.descendants);
  case TIMELINE_DELETE:
    return deleteFromContexts(state, action.id);
  case TIMELINE_CONTEXT_UPDATE:
    return updateContext(state, action.status, action.references);
  default:
    return state;
  }
};

@@ -845,25 +845,34 @@
 exts = (
-s
+immutableS
 tate, id
 ) =%3E %7B%0A 
@@ -867,48 +867,312 @@
 , id
+s
 ) =%3E 
-%7B%0A  state.getIn(%5B'descendants', id%5D
+immutableState.withMutations(state =%3E %7B%0A  state.update('ancestors', immutableAncestors =%3E immutableAncestors.withMutations(ancestors =%3E %7B%0A    state.update('descendants', immutableDescendants =%3E immutableDescendants.withMutations(descendants =%3E %7B%0A      ids.forEach(id =%3E %7B%0A        descendants.get(id
 , Im
@@ -1220,45 +1220,31 @@
     
-state = state.updateIn(%5B'ancestors', 
+      ancestors.update(
 desc
@@ -1251,17 +1251,16 @@
 endantId
-%5D
 , Immuta
@@ -1312,32 +1312,38 @@
 temId === id));%0A
+      
   %7D);%0A%0A  state.g
@@ -1339,22 +1339,14 @@
 %0A%0A  
-state.getIn(%5B'
+      
 ance
@@ -1350,22 +1350,23 @@
 ncestors
-', 
+.get(
 id
-%5D
 , Immuta
@@ -1408,47 +1408,33 @@
     
-state = state.updateIn(%5B'descendants', 
+      descendants.update(
 ance
@@ -1439,17 +1439,16 @@
 cestorId
-%5D
 , Immuta
@@ -1508,16 +1508,22 @@
 = id));%0A
+      
   %7D);%0A%0A 
@@ -1527,63 +1527,46 @@
 %0A%0A  
-state = state.deleteIn(%5B'descendants', id%5D).deleteIn(%5B'
+      descendants.delete(id);%0A        
 ance
@@ -1574,35 +1574,49 @@
 tors
-', 
+.delete(
 id
-%5D
 );%0A
-%0A  return state
+      %7D);%0A    %7D));%0A  %7D))
 ;%0A%7D
+)
 ;%0A%0Ac
@@ -1661,50 +1661,49 @@
 ship
-) =%3E %7B%0A  return state.map(%0A    s
+, statuses) =%3E %7B%0A  const ownedS
 tatus
-e
+Id
 s =
-%3E
  sta
@@ -1715,23 +1715,16 @@
 .filter(
-%0A      
 status =
@@ -1751,9 +1751,9 @@
 t') 
-!
+=
 == r
@@ -1767,16 +1767,134 @@
 ship.id)
+%0A                                 .map(status =%3E status.get('id'));%0A%0A  return deleteFromContexts(state, ownedStatusIds
 );%0A%7D;%0A%0Ac
@@ -2446,16 +2446,33 @@
 tionship
+, action.statuses
 );%0A  cas
@@ -2634,32 +2634,33 @@
 Contexts(state, 
+%5B
 action.id);%0A  ca
@@ -2652,16 +2652,17 @@
 ction.id
+%5D
 );%0A  cas

Fix status filtering in contexts reducer