{% include "vue/plugins.js" %}

{% if settings.DEBUG %}
Vue.config.devtools = true
{% endif %}

Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(EncryptionPlugin)

Vue.config.delimiters = ["[[", "]]"];

{% for name, path in components.items %}
    {% include path %}
    Vue.component("{{ name }}", {{ name }})
{% endfor %}


const routes = [
    { path: '/', component: null },
    {% for name, path in components.items %}
    {
        path: {{ name }}.router_path,
        name: "{{ name }}",
        component: {{ name }},
    },
    {% endfor %}
]

{% include "vue/stores.js" %}

const router = new VueRouter({routes})
const approuter = new Vue({
    router,
    vuetify: new Vuetify(),
    store: store,
    el: "#main",
    data: {
        uuid: "{{ user_settings.id }}",
        ready: false,
        search: '',
    },

    computed: {
        locked: function() {
            return this.$store.state.encryption.aes_key == null || this.$store.state.encryption.keyPair?.privateKey == null
        }
    },

    async created () {

        if (operations == undefined) {

            Swal.fire({title: "{{_('The application cannot be launched. Webcrypto is not available.<br><br>Try another browser!') | escapejs}}", icon: "error", showConfirmButton: false})

        } else {

            // Try to generate a random keyPair and encrypting stuff before accepting the client
            try {

                const keyPair = await this.generateKeyPair()

                this.ready = true

            } catch (err) {

                Swal.fire({title: "{{_('An error occured during testing Webcrypto. Please use a compatible browser.') | escapejs}}", icon: "error", showConfirmButton: false})

            }

        }
    },

    methods: {
        async load_keys (aes_key) {
            try {

                const response = await this.$http.get(Urls["users:keys"]())

                const iv_private = `${this.uuid}--private`
                const iv_public = `${this.uuid}--public`

                if (response.data.privateKey != null) {

                    const keyPair = {
                        privateKey: await this.unwrapKey(aes_key, response.data.privateKey, iv_private, ["decrypt"]),
                        publicKey: await this.unwrapKey(aes_key, response.data.publicKey, iv_public, ["encrypt"]),
                    }

                    this.$store.commit('encryption/updateKeyPair', keyPair)

                    Swal.fire({title: "{{_('Successfully loaded K356!') | escapejs}}", icon: "success", position:"top-end", showConfirmButton: false, toast: true, timer: 1000});

                } else {

                    const keyPair = await this.generateKeyPair()

                    await this.$http.post(
                        Urls["users:keys"](),
                        {
                            privateKey: await this.wrapKey(keyPair.privateKey, aes_key, iv_private),
                            publicKey: await this.wrapKey(keyPair.publicKey, aes_key, iv_public),
                        }
                    )

                    this.$store.commit('encryption/updateKeyPair', keyPair)

                    Swal.fire({title: "{{_('Successfully created K356!') | escapejs}}", icon: "success", position:"top-end", showConfirmButton: false, toast: true, timer: 1000});

                }

                this.load_items()
                this.load_properties()
                this.load_relations()

            } catch (err) {

                Swal.fire({title: "{{_('Error during unwrapping of private key.<br><br>Maybe your password is wrong?') | escapejs}}", icon: "error", showConfirmButton: false})

                console.error(err)

            }

        },

        update_key: function(key) {
            this.$store.commit('encryption/updateAesKey', key)

            this.load_keys(key)
        },

        lock_me: function() {
            this.$store.commit('encryption/updateKeyPair', null)
            this.$store.commit('encryption/updateAesKey', null)

            // Lock all stores
            this.$store.commit('encryption/lock')
            this.$store.commit('items/lock')
            this.$store.commit('types/lock')
            this.$store.commit('relations/lock')
            this.$store.commit('properties/lock')
            this.$store.commit('linkedProperties/lock')
            this.$store.commit('relationProperties/lock')
        },

        async load_items () {

            const response = await this.$http.get(Urls["items:list"]())

            this.$store.state.items.headers = response.data.result.items_headers
            this.$store.state.types.headers = response.data.result.types_headers

            this.$store.dispatch("items/setItems", { self: this, items: response.data.result.items })
            this.$store.dispatch("types/setItems", { self: this, items: response.data.result.types })

        },

        async load_properties () {

            const response = await this.$http.get(Urls["items:property.list"]())

            this.$store.state.properties.headers = response.data.result.properties_headers
            this.$store.state.linkedProperties.headers = response.data.result.linked_properties_headers
            this.$store.state.relationProperties.headers = response.data.result.relation_properties_headers

            this.$store.dispatch("properties/setItems", { self: this, items: response.data.result.properties })
            this.$store.dispatch("linkedProperties/setItems", { self: this, items: response.data.result.linked_properties })
            this.$store.dispatch("relationProperties/setItems", { self: this, items: response.data.result.relation_properties })

        },

        async load_relations () {

            const response = await this.$http.get(Urls["items:relation.list"]())

            this.$store.state.relations.headers = response.data.result.headers

            this.$store.dispatch("relations/setItems", { self: this, items: response.data.result.relations })

        },
    }
})

router.beforeEach((to, from, next) => {
    // Prevent from routing when locked or loading.
    next(!approuter.locked)
})
