import { createSelector } from 'reselect';
import uniqBy from 'lodash/uniqBy';
import sumBy from 'lodash/sumBy';
import findIndex from 'lodash/findIndex';
import { sortByKey } from 'utils/data';
import { format } from 'd3-format';

import { getAdminPath } from '../../../utils';

// get list data
const getData = state => state.data || null;
const getSettings = state => state.settings || null;
const getLocation = state => state.payload || null;
const getQuery = state => state.query || null;
const getLocationsMeta = state =>
  state[state.adminKey] || state.countries || null;
const getColors = state => state.colors || null;
const getIndicator = state => state.indicator || null;
const getCurrentLocation = state => state.currentLocation || null;
const getCurrentLabel = state => state.currentLabel || null;
const getAdminLevel = state => state.adminLevel || null;
const getSentences = state => state.config.sentences || null;
const getParentLocation = state => state[state.parentLevel] || null;

export const getSortedData = createSelector(
  [getData, getSettings],
  (data, settings) => {
    if (!data || !data.length) return null;
    return sortByKey(
      uniqBy(data, 'id'),
      settings.unit === 'ha' ? 'gain' : 'percentage',
      true
    ).map((d, i) => ({
      ...d,
      rank: i + 1
    }));
  }
);

export const parseData = createSelector(
  [
    getSortedData,
    getSettings,
    getLocation,
    getQuery,
    getCurrentLocation,
    getLocationsMeta,
    getColors
  ],
  (data, settings, location, query, currentLocation, meta, colors) => {
    if (!data || !data.length) return null;
    let dataTrimmed = [];
    data.forEach(d => {
      const locationMeta = meta && meta.find(l => d.id === l.value);
      if (locationMeta) {
        dataTrimmed.push({
          ...d,
          label: locationMeta.label
        });
      }
    });
    dataTrimmed = dataTrimmed.map((d, i) => ({
      ...d,
      rank: i + 1
    }));
    if (location.country) {
      const locationIndex = findIndex(
        dataTrimmed,
        d => d.id === currentLocation.value
      );
      let trimStart = locationIndex - 2;
      let trimEnd = locationIndex + 3;
      if (locationIndex < 2) {
        trimStart = 0;
        trimEnd = 5;
      }
      if (locationIndex > dataTrimmed.length - 3) {
        trimStart = dataTrimmed.length - 5;
        trimEnd = dataTrimmed.length;
      }
      dataTrimmed = dataTrimmed.slice(trimStart, trimEnd);
    }
    return dataTrimmed.map(d => ({
      ...d,
      color: colors.main,
      path: getAdminPath({
        ...location,
        country: location.region && location.country,
        query,
        id: d.id
      }),
      value: settings.unit === 'ha' ? d.gain : d.percentage
    }));
  }
);

export const getSentence = createSelector(
  [
    getSortedData,
    getIndicator,
    getCurrentLocation,
    getCurrentLabel,
    getSentences,
    getParentLocation,
    getAdminLevel
  ],
  (
    data,
    indicator,
    currentLocation,
    currentLabel,
    sentences,
    parent,
    adminLevel
  ) => {
    if (!data || !data.length) return null;
    const {
      initial,
      withIndicator,
      regionInitial,
      regionWithIndicator,
      globalInitial,
      globalWithIndicator
    } = sentences;
    const locationData =
      currentLocation && data.find(l => l.id === currentLocation.value);
    const gain = locationData ? locationData.gain : sumBy(data, 'gain');
    const gainPercent = gain ? 100 * gain / sumBy(data, 'gain') : 0;
    const areaPercent = (locationData && locationData.percentage) || 0;

    const params = {
      location: currentLabel === 'global' ? 'globally' : currentLabel,
      gain: gain < 1 ? `${format('.3r')(gain)}ha` : `${format('.3s')(gain)}ha`,
      indicator: (indicator && indicator.label.toLowerCase()) || 'region-wide',
      percent: areaPercent >= 0.1 ? `${format('.2r')(areaPercent)}%` : '<0.1%',
      gainPercent:
        gainPercent >= 0.1 ? `${format('.2r')(gainPercent)}%` : '<0.1%',
      parent: parent && parent.label
    };

    let sentence = indicator ? withIndicator : initial;
    if (adminLevel === 'region' || adminLevel === 'subRegion') {
      sentence = indicator ? regionWithIndicator : regionInitial;
    } else if (adminLevel === 'global' || adminLevel === 'subRegion') {
      sentence = indicator ? globalWithIndicator : globalInitial;
    }

    return {
      sentence,
      params
    };
  }
);

@@ -994,16 +994,126 @@
  null;%0A%0A
+const haveData = (data, currentLocation) =%3E%0A  data.filter(item =%3E item.id === currentLocation.value).length;%0A%0A
 export c
@@ -1558,24 +1558,45 @@
 ntLocation,%0A
+    getCurrentLabel,%0A
     getLocat
@@ -1623,29 +1623,38 @@
 ors%0A  %5D,%0A  (
+%0A    
 data,
+%0A   
  settings, l
@@ -1651,16 +1651,20 @@
 ettings,
+%0A   
  locatio
@@ -1665,23 +1665,31 @@
 ocation,
+%0A   
  query,
+%0A   
  current
@@ -1701,21 +1701,50 @@
 ion,
+%0A    currentLabel,%0A   
  meta,
+%0A   
  colors
+%0A  
 ) =%3E
@@ -1750,32 +1750,39 @@
 %3E %7B%0A    if (
+%0A      
 !data %7C%7C
  !data.lengt
@@ -1761,32 +1761,38 @@
 (%0A      !data %7C%7C
+%0A     
  !data.length) r
@@ -1780,33 +1780,113 @@
     !data.length
-)
+ %7C%7C%0A      (currentLabel !== 'global' && !haveData(data, currentLocation))%0A    ) %7B
  return null;%0A  
@@ -1878,24 +1878,27 @@
 return null;
+ %7D%0A
 %0A    let dat
@@ -3345,32 +3345,39 @@
 %3E %7B%0A    if (
+%0A      
 !data %7C%7C
  !data.lengt
@@ -3356,32 +3356,38 @@
 (%0A      !data %7C%7C
+%0A     
  !data.length) r
@@ -3375,33 +3375,113 @@
     !data.length
-)
+ %7C%7C%0A      (currentLabel !== 'global' && !haveData(data, currentLocation))%0A    ) %7B
  return null;%0A  
@@ -3473,24 +3473,26 @@
 return null;
+ %7D
 %0A    const %7B

fix for no data cases