/** @module swisstennis/state */
import { put, takeEvery } from 'redux-saga/effects'
import api from '../api'
import moment from 'moment'

/**
 * state.js
 *
 * Collection of everything which has to do with state changes.
 **/

/** actionTypes define what actions are handeled by the reducer. */
export const actions = {
  setFilter: (data) => {
    return {
      type: 'SZTM/SET_FILTER',
      data
    }
  },
  fileListRequest: () => {
    return {
      type: 'SZTM/FILE_LIST_REQUEST',
    }
  },
  fileListSuccess: data => {
    return {
      type: 'SZTM/FILE_LIST_SUCCESS',
      data
    }
  },
  fileListFailure: error => {
    return {
      type: 'SZTM/FILE_LIST_FAILURE',
      error
    }
  },
  resetProgress: () => {
    return {
      type: 'SZTM/RESET_PROGRESS'
    }
  },
  generateListRequest: (data) => {
    return {
      type: 'SZTM/GENERATE_LIST_REQUEST',
      data
    }
  },
  generateListSuccess: (data) => {
    return {
      type: 'SZTM/GENERATE_LIST_SUCCESS',
      data
    }
  },
  generateListFailure: error => {
    return {
      type: 'SZTM/GENERATE_LIST_FAILURE',
      error
    }
  },
  generateZipRequest: (data) => {
    return {
      type: 'SZTM/GENERATE_ZIP_REQUEST',
      data
    }
  },
  generateZipSuccess: (data) => {
    return {
      type: 'SZTM/GENERATE_ZIP_SUCCESS',
      data
    }
  },
  generateZipFailure: error => {
    return {
      type: 'SZTM/GENERATE_ZIP_FAILURE',
      error
    }
  },
}
console.log('State actions', actions)

/** state definition */
const emptyFilter = {
  date: '',
}

export const state = {
  files: [],
  fileListStatus: 'uninitialized',
  filteredFiles: [],
  filter: emptyFilter,
  progress: []
}
console.log('State state', state)

/** reducer is called by the redux dispatcher and handles all component actions */
export function reducer (state = [], action) {
  switch (action.type) {
    case 'SZTM/SET_FILTER':
      const filter = { ...state.filter, ...action.data }
      const filteredFiles = state.files.filter(file => {
        const dateString = moment.unix(filter.date).format('YYYYMMDD')
        return filter.date ? file.filename.includes(dateString) : true
      })
      return { ...state, filter, filteredFiles }
    case 'SZTM/FILE_LIST_REQUEST':
      return { ...state, fileListStatus: 'request' }
    case 'SZTM/FILE_LIST_SUCCESS':
      return { ...state, fileListStatus: 'success', files: action.data }
    case 'SZTM/FILE_LIST_FAILURE':
      return { ...state, fileListStatus: 'failure' }
    case 'SZTM/RESET_PROGRESS':
      return { ...state, progress: [] }
    case 'SZTM/GENERATE_LIST_REQUEST':
      return { ...state, playerListDownloadStatus: 'request' }
    case 'SZTM/GENERATE_LIST_SUCCESS':
      return { ...state, playerListDownloadStatus: 'success', 
        files: [ ...state.files, action.data.paylistFile, action.data.scheduleFile ],
        progress: [ ...state.progress, action.data.place ] }
    case 'SZTM/GENERATE_LIST_FAILURE':
      return { ...state, playerListDownloadStatus: 'failure' }
    case 'SZTM/GENERATE_ZIP_REQUEST':
      return { ...state, playerListDownloadStatus: 'request' }
    case 'SZTM/GENERATE_ZIP_SUCCESS':
      return { ...state, playerListDownloadStatus: 'success', files: [ ...state.files, action.data ] }
    case 'SZTM/GENERATE_ZIP_FAILURE':
      return { ...state, playerListDownloadStatus: 'failure' }
    default:
      return state
  }
}

function * fileList (action) {
  yield put(api.actions.apiRequest({
    path: `api/sztm/files`,
    method: 'GET',
    onSuccess: [ actions.fileListSuccess, actions.setFilter ],
    onFailure: actions.fileListFailure
  }))
}

function * generateList (action) {
  yield put(api.actions.apiRequest({
    path: `api/sztm/pdf`,
    method: 'POST',
    body: JSON.stringify(action.data),
    onSuccess: [ actions.generateListSuccess, actions.setFilter ],
    onFailure: actions.generateListFailure
  }))
}

function * generateZip (action) {
  yield put(api.actions.apiRequest({
    path: `api/sztm/zip`,
    method: 'POST',
    body: JSON.stringify(action.data),
    onSuccess: [ actions.generateZipSuccess, actions.setFilter ],
    onFailure: actions.generateZipFailure
  }))
}

/** sagas are asynchronous workers (JS generators) to handle the state. */
export function * saga () {
  console.log('Config saga started.')
  yield takeEvery('SZTM/FILE_LIST_REQUEST', fileList)
  yield takeEvery('SZTM/GENERATE_LIST_REQUEST', generateList)
  yield takeEvery('SZTM/GENERATE_ZIP_REQUEST', generateZip)
}
