import _omit from 'lodash/omit'
import { ref } from 'vue'
import { getNotesAPI } from '@/libs/core/getNotesAPI'

const categories = ref([])
const searchResults = ref([])
const notesChangeCount = ref(0)

let listenersInitialized = false

const setupListeners = () => {
    if (listenersInitialized || typeof window === 'undefined') return
    listenersInitialized = true

    const updateCacheCount = async (note) => {
        const api = await getNotesAPI()
        await api.updateNote(
            note.id,
            _omit(note, ['id', 'createdAt', 'updatedAt']),
        )

        notesChangeCount.value++
    }

    window.api.onNoteCreated(updateCacheCount)
    window.api.onNoteUpdated(updateCacheCount)
    window.api.onPluginChanged(async () => {
        const api = await getNotesAPI()
        await api.init()

        notesChangeCount.value++
    })

    // Todo update cache
    window.api.onNoteDeleted(() => {
        notesChangeCount.value++
    })
}

const broadcastChange = (event, data) => {
    window.api.notifyNoteChanged(event, data)
}

setupListeners()

export default () => {
    /* -------------------------
     Initialization
    --------------------------*/
    const loadCategories = async () => {
        const api = await getNotesAPI()
        categories.value = api.getCategories()
    }

    const loadCategoryNotes = async (category = null) => {
        const api = await getNotesAPI()
        return api.getCategoryNotes(category)
    }

    const loadNote = async (id) => {
        const api = await getNotesAPI()
        return api.getNote(id)
    }

    /* -------------------------
     Create
    --------------------------*/
    const createNote = async (metadata, content, plainText = '') => {
        const api = await getNotesAPI()
        const note = await api.createNote(metadata, content, plainText)
        await loadCategories()
        broadcastChange('note-created', note)
        return note
    }

    /* -------------------------
     Update
    --------------------------*/
    const updateNote = async (id, updates) => {
        const api = await getNotesAPI()

        const note = await api.updateNote(id, updates)

        if (updates.category !== undefined || updates.title !== undefined) {
            await loadCategories()
        }

        broadcastChange('note-updated', note)

        return note
    }

    const updateCategory = async (category, update) => {
        const notes = await loadCategoryNotes(category)

        for (const note of notes) {
            await updateNote(note.id, { category: update })
        }

        await loadCategories()
    }

    /* -------------------------
     Delete
    --------------------------*/
    const deleteNote = async (id) => {
        const api = await getNotesAPI()
        await api.deleteNote(id)
        await loadCategories()
        broadcastChange('note-deleted', { id })
    }

    /* -------------------------
     Search
    --------------------------*/
    const search = async (query) => {
        const api = await getNotesAPI()

        if (!query) {
            searchResults.value = []
            return
        }

        searchResults.value = api.search(query)
    }

    return {
        categories,
        searchResults,
        notesChangeCount,

        loadCategories,
        loadCategoryNotes,
        loadNote,

        createNote,
        updateNote,
        updateCategory,
        deleteNote,

        search,
    }
}
