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

export default class Database {

  static purgeStorage () {
    localStorage.removeItem(window.env.localStorageKey)
  }

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

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

    return JSON.parse(storage || '[]')
  }

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

  /**
   *
   * @param archive
   * @param n
   * @param fakerAmount
   * @returns {*}
   */
  static getNotes (archive = false, n = window.env.prePopulateAmount, fakerAmount = window.env.fakerAmount) {
    let notes = Database.getStorage(true, fakerAmount)

    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 archive
   * @param n
   * @param fakerAmount
   * @returns {*[]|[]}
   */
  static getNotesSanitized (archive = false, n = window.env.prePopulateAmount, fakerAmount = window.env.fakerAmount) {
    let notes = Database.getNotes(archive, n, fakerAmount)
    notes = Validation.allAgainstSchema(notes, window.env.schemas.note)
    return n > 0 ? notes.slice(0, n) : notes
  }

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

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

    let note = Database.getNoteByID(id)

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

    return false
  }

  /**
   *
   * @param id
   */
  static unArchiveNote (id) {
    this.archiveNote(id, '')
  }

  /**
   *
   * @param fakerAmount
   * @returns {*[]}
   */
  static getAnalytics (fakerAmount = window.env.fakerAmount) {
    const analytics = []
    const data = Database.getStorage(true, fakerAmount)
    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) => {
        // Important! using 'Double Equality operator (==)'
        // noinspection EqualityComparisonWithCoercionJS
        analytics.push({
          title: cat,
          archived: isArchive.filter(el => el[cat] === 'on').length,
          // eslint-disable-next-line
          active: isArchive.filter(el => el[cat] == '').length,
        })
      })
    }

    return analytics
  }

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

  /**
   *
   * @param noteToStore
   */
  static saveNote (noteToStore = null) {

    if (Object.keys(noteToStore).length === 0) {
      return 'Passed data is empty'
    }

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

    if (isValid.status === true) {

      noteToStore = isValid.data
      const notes = Database.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)
      }

      Database.saveNotesToStorage(notes)

    } else {
        return 'Passed data is not valid:\r\n    - ' + isValid.error_text.join('\r\n    - ')
    }

    return true
  }
}