import DOMController from './DOMController'
import Validation from './ValidationController'
import { fakerDB } from '../faker'
import Alert from './AlertController'

export default class NotesAPI {

  /**
   *
   * @returns {any}
   * @param save
   */
  static getStorage (save = true) {
    const key = window.env.localStorageKey
    let storage = localStorage.getItem(key)

    if (storage === null) {
      storage = JSON.stringify(fakerDB(env.fakerAmount)) || '[]'
      if (save) localStorage.setItem(key, storage)
    }

    return JSON.parse(storage)
  }

  /**
   *
   * @param n
   * @param archive
   * @returns {*}
   */
  static getNotes (n = 0, archive = false) {

    let notes = NotesAPI.getStorage()

    if (typeof archive === 'boolean') {
      notes = notes.filter(el => (archive ? el.archive === 'on' : el.archive !== 'on'))
    }

    notes.sort((a, b) => {
      return new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1
    })

    return n > 0 ? notes.slice(0, n) : notes
  }

  /**
   *
   * @param id
   * @returns {*}
   */
  static getNoteByID (id) {
    return NotesAPI.getStorage().filter(el => el.id === id)
  }

  /**
   *
   * @param n
   * @param archive
   * @returns {*[]|[]}
   */
  static getNotesSanitized (n = 0, archive = false) {
    let notes = NotesAPI.getNotes(0, archive)

    notes = Validation.allAgainstSchema(notes, window.env.schemas.note)
    return n > 0 ? notes.slice(0, n) : notes
  }

  /**
   *
   * @param noteToStore
   * @param action
   */
  static saveNote (noteToStore = null, action = 'modal') {

    if (Object.keys(noteToStore).length === 0) {
      noteToStore = DOMController.getFormData()
    }

    const isValid = Validation.againstSchema(noteToStore, window.env.schemas.note)

    if (isValid.status === true) {

      noteToStore = isValid.data
      const notes = NotesAPI.getNotes(0, null)
      const noteExists = notes.find(note => note.id === +noteToStore.id)

      if (noteExists) {
        noteExists.title = noteToStore.title
        noteExists.content = noteToStore.content
        noteExists.category = noteToStore.category
        noteExists.archive = noteToStore.archive || ''
        noteExists.updatedAt = new Date().toISOString()
      } else {
        noteToStore.id = Math.floor(100000 + Math.random() * 900000)
        noteToStore.archive = noteToStore.archive || ''
        noteToStore.createdAt = new Date().toISOString()
        notes.push(noteToStore)
      }

      NotesAPI.saveNotesToStorage(notes)

      if (action === 'modal') {
        //TODO: Need to implement in different way
        document.querySelector(window.env.querySelectors.noteEditForm).closest('.modal').remove()
      }

    } else {
      Alert.displayDialog('Could save the note! ' + isValid.errors.join(', '), 6000, 2) //, document.getElementById('modalMsgBox')
    }

  }

  /**
   *
   * @param id
   */
  static deleteNote (id) {
    const notes = NotesAPI.getStorage()
    const filteredNotesByID = notes.filter(note => note.id !== id)
    NotesAPI.saveNotesToStorage(filteredNotesByID)
  }

  static unArchiveNote (id) {
    this.archiveNote(id, '')
  }

  /**
   *
   * @param id
   * @param value
   */
  static archiveNote (id, value = 'on') {

    if (value !== '') value = 'on'

    let note = NotesAPI.getNoteByID(id)

    if (note.length > 0 && note[0].archive !== value) {
      note[0].archive = value
      NotesAPI.saveNote(note[0], 'archive')
      return true
    }

    return false
  }

  /**
   *
   * @param notes
   * @param key
   */
  static saveNotesToStorage (notes, key = window.env.localStorageKey) {
    localStorage.setItem(key, JSON.stringify(notes, null, 2))
  }

  /**
   *
   * @returns {{}}
   */
  static getAnalytics () {

    const analytics = {}
    const data = NotesAPI.getStorage()
    const cats = [...new Set(data.map(item => item.category))]

    if (typeof cats[0] !== 'undefined') {
      const isArchive = data.map(item => {
        const container = {}
        container[item.category] = item.archive
        return container
      })

      cats.forEach((cat, i) => {
        analytics[cat] = {
          Active: isArchive.filter(el => el[cat] === 'on').length,
          Archived: isArchive.filter(el => el[cat] == '').length,
        }
      })
    }

    return analytics
  }
}