import Ember from 'ember';
import _ from 'lodash';

const FILTER_QUERY_PARAMS = ['date', 'discourse', 'language', 'location', 'theme'];

export default Ember.Service.extend({

    date: null,
    discourse: null,
    language: null,
    location: null,
    theme: null,

    queryParams: FILTER_QUERY_PARAMS,

    getRouteQueryParams: function(exclude) {
        return _.reduce(FILTER_QUERY_PARAMS, function(res, f) {
            if(f !== exclude) {
                res[f] = {
                    refreshModel: true
                };
            }
            return res;
        }, {});
    },

    getControllerQueryParams: function(exclude) {
        return _.filter(FILTER_QUERY_PARAMS, function(f) { return f !== exclude; });
    },

    queryParamsValues: Ember.computed('date', 'discourse', 'language', 'location', 'theme', function() {
        return _.reduce(this.getProperties(FILTER_QUERY_PARAMS), function(res, v, k) {
            if(v) {
              res[k] = v;
            }
            return res;
        }, {});
    }),
    queryParamsValuesURI: Ember.computed('date', 'discourse', 'language', 'location', 'theme', function() {
        return _.reduce(this.getProperties(FILTER_QUERY_PARAMS), function(res, v, k) {
            if(v) {
              if(k === "date" || k === "discourse"  || k === "theme" ) {
                  k = k + "[]";
              }
              res[k] = v;
            }
            return res;
        }, {});
    }),
    removeFilter: function(filter, value) {
        switch(filter) {
            case 'date':
            case 'discourse':
            case 'theme': {
                let values = this.get(filter);
                if(values === null) {
                    return;
                }
                values = _.without(values, value);
                if(values.length === 0) {
                    this.set(filter, null);
                } else {
                    this.set(filter, values);
                }
                break;
            }
            case 'language':
            case 'location':
                this.set(filter, null);
                break;
        }
    },
    setFilter: function(filter, value) {
        switch(filter) {
            case 'date':
            case 'discourse':
            case 'theme': {
                let filterValues = this.get(filter);
                if(filterValues === null) {
                    filterValues = [];
                }
                if(!_.includes(filterValues, value)) {
                    filterValues = filterValues.slice(0); //clone
                    filterValues.push(value);
                    filterValues.sort();
                    this.set(filter, filterValues);
                    return true;
                }
                return false;
            }
            case 'language':
            case 'location':
                if(this.get(filter) !== value) {
                    this.set(filter, value);
                    return true;
                }
                return false;
        }
    },
    serializeQueryParam(value/*, urlKey, defaultValueType*/) {
        if (_.isArray(value)) {
          return value;
        }
        return `${value}`;
    },
    deserializeQueryParam(value, urlKey, defaultValueType) {
        if (urlKey === 'id' || urlKey === 'date' || urlKey === 'theme' || urlKey === 'discourse') {
            if(_.isArray(value)) {
                return value;
            } else {
                var parsedValue = Ember.A(JSON.parse(value));
                if (_.isArray(parsedValue)) {
                    return parsedValue;
                } else {
                    return Ember.A([ parsedValue, ]);
                }
            }
        } else if (defaultValueType === 'boolean') {
            return (value === 'true') ? true : false;
        } else if (defaultValueType === 'number') {
            return (Number(value)).valueOf();
        } else if (defaultValueType === 'array') {
            return Ember.A(JSON.parse(value));
        }
        return value;
    },
    dateList: Ember.computed('date.[]', {
        get: function() {
            const dates = this.get('date');
            if(dates === null) {
                return [];
            }
            const res = _.reduce(dates, function(res, d) {
                let m = d.match(/^(\d+)(?:-(\d+))?$/);
                if(m) {
                    let start = parseInt(m[1]);
                    let end = parseInt(m[2]);
                    if(isNaN(end)) {
                        res.push(parseInt(m[1]));
                    } else {
                        res = res.concat(_.range(start,end+1));
                    }
                }
                return res;
            }, []).sort();
            return res;
        },
        set: function(key, values) {
            var srcDateList = _.clone(values).sort();
            let start = null;
            let end = null;
            var pushValues = function(s,e,valuesList) {
                if(s === e) {
                    valuesList.push(s.toString());
                } else {
                    valuesList.push(s.toString()+"-"+e.toString());
                }
            };
            let dateList = _.reduce(srcDateList, function(res, d, i) {
                if(start === null) {
                    start = end = d;
                }
                if(d > (end + 1)) {
                    pushValues(start, end, res);
                    start = end = d;
                } else {
                    end = d;
                }
                if(i === (srcDateList.length - 1)) {
                    pushValues(start, end, res);
                }
                return res;
          }, []);
          if(dateList.length === 0) {
              dateList = null;
          }
          this.set('date', dateList);
          return srcDateList;
      }
    }),

});
