import { createDuck } from 'redux-duck'
import { fromJS, List } from 'immutable'
import gql from '../util/gql'

const COSTY_FIELD_COOLDOWN = 60*1000; // in seconds. query costy fields only 1 time within 60 seconds

const {defineType, createReducer, createAction} = createDuck('articleList');

// Action Types
//

const LOAD = defineType('LOAD');
const LOAD_AUTH_FIELDS = defineType('LOAD_AUTH_FIELDS');

// Action creators
//

let isInCooldown = false;
let lastFilter;
export const load = ({
  filter = 'all',
  orderBy = 'replyRequestCount',
  before, after,
}) => dispatch => {
  if(lastFilter !== filter) {
    // Invalidate costy field cache when filter changes
    isInCooldown = false;
  }

  lastFilter = filter;

  if(filter === 'solved') {
    filter = {replyCount: {GT: 0}};
  } else if(filter === 'unsolved') {
    filter = {replyCount: {EQ: 0}};
  } else {
    filter = undefined;
  }

  return gql`query(
    $filter: ListArticleFilter,
    $orderBy: [ListArticleOrderBy],
    $before: String,
    $after: String,
  ) {
    ListArticles(
      filter: $filter
      orderBy: $orderBy
      before: $before
      after: $after
      first: 25
    ) {
      edges {
        node {
          id
          text
          replyCount
        }
        cursor
      }

      ${
        isInCooldown ? '' : /* costy fields */ `
          pageInfo {
            firstCursor
            lastCursor
          }
          totalCount
        `
      }
    }
  }`({
    filter,
    orderBy: [{[orderBy]: 'DESC'}],
    before,
    after,
  }).then((resp) => {
    // only ignore costy fields on browser.
    //
    if(typeof window !== 'undefined' && !isInCooldown) {
      isInCooldown = true;
      setTimeout(resetCooldown, COSTY_FIELD_COOLDOWN);
    }
    dispatch(createAction(LOAD)(
      resp.getIn(['data', 'ListArticles'], List())
    ));
  });
}

export const loadAuthFields = ({
  filter = 'all',
  orderBy = 'replyRequestCount',
  before, after,
}) => dispatch => {
  return gql`query(
    $filter: ListArticleFilter,
    $orderBy: [ListArticleOrderBy],
    $before: String,
    $after: String,
  ) {
    ListArticles(
      filter: $filter
      orderBy: $orderBy
      before: $before
      after: $after
      first: 25
    ) {
      edges {
        node {
          id
          requestedForReply
        }
      }
    }
  }`({
    filter,
    orderBy: [{[orderBy]: 'DESC'}],
    before,
    after,
  }).then((resp) => {
    dispatch(createAction(LOAD_AUTH_FIELDS)(
      resp.getIn(['data', 'ListArticles', 'edges'], List())
    ));
  });
}

// Reducer
//

const initialState = fromJS({
  state: {isLoading: false},
  edges: null,
  firstCursor: null,
  lastCursor: null,
  totalCount: null,
  authFields: {},
});

export default createReducer({
  [LOAD]: (state, {payload}) => state
    .set('edges', payload.get('edges'))
    .set('firstCursor', payload.getIn(['pageInfo', 'firstCursor']) || state.get('firstCursor'))
    .set('lastCursor', payload.getIn(['pageInfo', 'lastCursor']) || state.get('lastCursor'))
    .set('totalCount', payload.get('totalCount') || state.get('totalCount')),
  [LOAD_AUTH_FIELDS]: (state, {payload}) => state
    .set('authFields', Map(payload.map(article => [article.getIn(['node', 'id']), article.get('node')])))
}, initialState);


// Util
//

function resetCooldown() {
  isInCooldown = false;
}

@@ -54,16 +54,21 @@
 JS, List
+, Map
  %7D from 
@@ -79,16 +79,16 @@
 utable'%0A
-
 import g
@@ -1465,32 +1465,57 @@
  %7D%60(%7B%0A    filter
+: getFilterObject(filter)
 ,%0A    orderBy: %5B
@@ -2371,24 +2371,49 @@
 %7B%0A    filter
+: getFilterObject(filter)
 ,%0A    orderB
@@ -3369,16 +3369,16 @@
 own() %7B%0A
-
   isInCo
@@ -3391,12 +3391,220 @@
  = false;%0A%7D%0A
+%0Afunction getFilterObject(filter) %7B%0A  if(filter === 'solved') %7B%0A    return %7BreplyCount: %7BGT: 0%7D%7D;%0A  %7D else if(filter === 'unsolved') %7B%0A    return %7BreplyCount: %7BEQ: 0%7D%7D;%0A  %7D else %7B%0A    return undefined;%0A  %7D%0A%7D%0A

Fix filter handling