const ko = require('knockout')

const api = require('../../../../get-api-data')
const browser = require('../../../../browser')
const endpoints = require('../../../../api')
const querystring = require('../../../../get-url-parameter')

import { formatNeedsKO } from '../../requests/needs'
import { getKOSortAscFunc, getKOSortDescFunc } from '../../../../sorting'

import ProximitySearch from '../../../ProximitySearch'
import pushHistory from '../../../../history'
import GiveHelpClientGroup from '../GiveHelpClientGroup'

class NeedsListing {
  constructor () {
    this.proximitySearch = new ProximitySearch(this)
    this.clientGroup = new GiveHelpClientGroup()
    this.allNeeds = ko.observableArray()
    this.filters = ko.observableArray([
      { isActive: ko.observable(true), filterAction: () => this.clearFilter(), filterFunction: () => true, label: 'All' },
      { isActive: ko.observable(false), filterAction: () => this.filterForItems(), filterFunction: (n) => n.type() === 'items', label: 'Items' },
      { isActive: ko.observable(false), filterAction: () => this.filterForTime(), filterFunction: (n) => n.type() === 'time', label: 'Time' },
      { isActive: ko.observable(false), filterAction: () => this.filterForMoney(), filterFunction: (n) => n.type() === 'money', label: 'Money' }
    ])
    this.currentFilterFunction = ko.observable(this.filters().find((f) => f.label === 'All').filterFunction)
    this.sorts = ko.observableArray([
      { isActive: ko.observable(true), sortAction: () => this.sortByDateAdded(), sortFunction: getKOSortDescFunc('neededDate'), label: 'Date Added' },
      { isActive: ko.observable(false), sortAction: () => this.sortByOrganisation(), sortFunction: getKOSortAscFunc('serviceProviderName'), label: 'Organisation' },
      { isActive: ko.observable(false), sortAction: () => this.sortByDistance(), sortFunction: getKOSortAscFunc('distanceAwayInMetres'), label: 'Distance' }
    ])
    this.currentSortFunction = ko.observable(this.sorts().find((f) => f.label === 'Date Added').sortFunction)
    this.isMoreToLoad = ko.observable(false)
    this.currentPageLinks = {}

    this.hasPostcode = ko.computed(() => this.proximitySearch.postcode() !== undefined && this.proximitySearch.postcode().length, this)
    this.priorityNeeds = ko.computed(() => this.allNeeds().filter((n) => n.isPriority()))
    this.nonPriorityNeeds = ko.computed(() => this.allNeeds().filter((n) => !n.isPriority()))
    this.needsToDisplay = ko.computed(() => [...this.priorityNeeds(), ...this.nonPriorityNeeds().filter(this.currentFilterFunction()).sort(this.currentSortFunction())], this)
    this.hasNeeds = ko.computed(() => this.needsToDisplay().length > 0, this)

    const postcodeInQuerystring = querystring.parameter('postcode')
    if (postcodeInQuerystring) {
      this.proximitySearch.postcode(postcodeInQuerystring)
      this.proximitySearch.search()
    } else if (this.proximitySearch.hasCoords()) {
      this.onProximitySearch()
    }

    browser.setOnHistoryPop((e) => {
      this.onBrowserHistoryBack(this, e)
    })
  }

  loadNextPage () {
    this.loadNeeds(endpoints.getFullUrl(this.currentPageLinks.next + `&clientGroup=${this.encodeClientGroupKey(this.clientGroup.clientGroupKey)}`))
  }

  onProximitySearch () {
    if (querystring.parameter('type')) {
      this.setActiveFilter(querystring.parameter('type'))
    }

    this.allNeeds([])
    this.loadNeeds(this.firstPageUrl)

    this.pushHistory()
  }

  onProximitySearchFail (error) {
    console.log(error)
    browser.redirect('/500')
  }

  onBrowserHistoryBack (thisDoobrey, e) {
    if (e.state) {
      this.setActiveFilter(e.state.type)
      if (e.state.postcode !== thisDoobrey.proximitySearch.postcode()) {
        thisDoobrey.proximitySearch.postcode(e.state.postcode)
        thisDoobrey.proximitySearch.search()
      }
    }
  }

  pushHistory () {
    pushHistory([
      { qsKey: 'postcode', getValue: () => this.proximitySearch.postcode() },
      {
        qsKey: 'type',
        getValue: () => {
          const activeFilter = this.filters().find((f) => f.isActive())
          return activeFilter
            ? activeFilter.label
            : null
        }
      }
    ])
  }

  filterForItems () {
    this.setActiveFilter('Items')
  }

  filterForTime () {
    this.setActiveFilter('Time')
  }

  filterForMoney () {
    this.setActiveFilter('Money')
  }

  clearFilter () {
    this.setActiveFilter('All')
  }

  setActiveFilter (reqFilter) {
    const filter = this.filters().find((f) => f.label === reqFilter)

    if (filter) {
      this.filters()
        .filter((f) => f.label !== reqFilter)
        .forEach((f) => f.isActive(false))

      filter.isActive(true)
      this.currentFilterFunction(filter.filterFunction)
      this.pushHistory()
    }
  }

  sortByOrganisation () {
    this.setActiveSort('Organisation')
  }

  sortByDistance () {
    this.setActiveSort('Distance')
  }

  sortByDateAdded () {
    this.setActiveSort('Date Added')
  }

  setActiveSort (reqSort) {
    this.sorts()
      .filter((f) => f.label !== reqSort)
      .forEach((f) => f.isActive(false))
    const sort = this.sorts().find((f) => f.label === reqSort)
    sort.isActive(true)
    this.currentSortFunction(sort.sortFunction)
  }

  loadNeeds (url) {
    browser.loading()
    api
      .data(url)
      .then((result) => {
        this.currentPageLinks = result.data.links
        this.allNeeds([...this.allNeeds(), ...formatNeedsKO(result.data.items, { latitude: this.proximitySearch.latitude, longitude: this.proximitySearch.longitude })])
        this.isMoreToLoad(result.data.links.next)

        browser.loaded()
      }, (_) => {
        browser.redirect('/500')
      })
  }

  get firstPageUrl () {
    const qsParts = {
      'latitude': this.proximitySearch.latitude,
      'longitude': this.proximitySearch.longitude,
      'pageSize': 1,
      'range': this.proximitySearch.range(),
      'clientGroup': this.encodeClientGroupKey(this.clientGroup.clientGroupKey)
    }
    const qs = Object.keys(qsParts)
      .map((k) => `${k}=${qsParts[k]}`)
      .join('&')

    return `${endpoints.needs}?${qs}`
  }

  encodeClientGroupKey (key) {
    if (key.charAt(key.length - 1) === '+') {
      return key.slice(0, -1) + '%2B'
    }
    return key
  }
}

module.exports = NeedsListing

@@ -5876,16 +5876,17 @@
 eSize': 
+2
 1,%0A     

Change page size