<template>
  <main>
    <v-form
      ref="form"
      v-model="properties.valid"
      lazy-validation
      :readonly="readOnly"
    >
      <v-container fluid class="container btnActions">
        <v-row>
          <v-col cols="12" sm="12">
            <slot name="form.button"></slot>
            <v-btn v-if="!readOnly" class="mr-4 ot_green ot_white--text" @click="submit">
              {{$t('save')}}
            </v-btn>
          </v-col>
        </v-row>
      </v-container>

      <slot name="form.input" v-bind="{entry,updateRepository}"></slot>

      <v-container fluid class="container btnActions">
        <v-row>
          <v-col cols="12" sm="12">
            <slot name="form.button"></slot>
            <v-btn v-if="!readOnly" class="mr-4 ot_green ot_white--text" @click="submit">
              {{$t('save')}}
            </v-btn>
          </v-col>
        </v-row>
      </v-container>
    </v-form>

    <lazy-LayoutDialog
      :show="showDialog"
    >
      <template v-slot:dialogText>
        <v-card-title class="text-h5 grey lighten-2">
          {{$t('attention')}}
        </v-card-title>
        <v-card-text>
          <br>
          <p>{{$t('quit_without_saving_warning')}}</p>
        </v-card-text>
      </template>
      <template v-slot:dialogBtn>
        <v-btn class="mr-4 submitBtn ot_green ot_white--text" @click="closeDialog">
          {{$t('back_to_form')}}
        </v-btn>
        <v-btn class="mr-4 submitBtn ot_green ot_white--text" @click="saveAndQuit">
          {{$t('save_and_quit')}}
        </v-btn>
        <v-btn class="mr-4 submitBtn ot_danger ot_white--text" @click="goEvenUnsavedData">
          {{$t('quit_form')}}
        </v-btn>
      </template>
    </lazy-LayoutDialog>
  </main>
</template>

<script lang="ts">
  import {computed, defineComponent, onBeforeMount, onBeforeUnmount, reactive, toRefs, useContext} from '@nuxtjs/composition-api'
  import {repositoryHelper} from "~/services/store/repository";
  import {queryHelper} from "~/services/store/query";
  import {Query} from "@vuex-orm/core";
  import {QUERY_TYPE, TYPE_ALERT} from "~/types/enums";
  import {alert} from "~/types/interfaces";

  export default defineComponent({
    props: {
      model: {
        type: Function,
        required: true
      },
      id: {
        type: Number,
        required: true
      },
      query: {
        type: Object as () => Query,
        required: true
      },
    },
    setup: function (props) {
      const {$dataPersister, store, app: {router, i18n}} = useContext()

      const {id, query} = toRefs(props)
      const repository = repositoryHelper.getRepository(props.model)
      const properties = reactive({
        valid: false,
        saveOk: false,
        saveKo: false
      })

      const readOnly = computed(() => {
        return false
      })

      const entry = computed(() => {
        return queryHelper.getFlattenEntry(query.value, id.value)
      })

      const handler = getEventHandler()

      const updateRepository = (newValue: string, field: string) => {
        addEventListener(handler)
        store.commit('form/setDirty', true)
        repositoryHelper.updateStoreFromField(repository, entry.value, newValue, field)
      }

      const submit = async () => {
        try {
          store.commit('form/setDirty', false)
          clearEventListener(handler)
          await $dataPersister.invoke({
            type: QUERY_TYPE.MODEL,
            model: props.model,
            id: id.value
          })

          const alert:alert = {
            type: TYPE_ALERT.SUCCESS,
            message: i18n.t('saveSuccess') as string
          }
          store.commit('page/setAlert', alert)

        } catch (error) {
          const alert:alert = {
            type: TYPE_ALERT.ALERT,
            message: error.message
          }
          store.commit('page/setAlert', alert)
        }
      }

      onBeforeMount(() => {
        clearEventListener(handler)
      })

      onBeforeUnmount(() => {
        clearEventListener(handler)
      })

      const showDialog = computed(() => {
        return store.state.form.showConfirmToLeave
      })

      const closeDialog = () => {
        store.commit('form/setShowConfirmToLeave', false)
      }

      const saveAndQuit = async () => {
        await submit()
        goEvenUnsavedData()
      }

      const goEvenUnsavedData = () => {
        store.commit('form/setDirty', false)
        store.commit('form/setShowConfirmToLeave', false)

        const entryCopy = query.value.first()
        if (entryCopy && entryCopy.$getAttributes()['originalState']) {
          repositoryHelper.persist(repository, entryCopy.$getAttributes()['originalState'])
        }

        if (router) {
          router.push(store.state.form.goAfterLeave)
        }
      }

      return {
        submit,
        updateRepository,
        properties,
        readOnly,
        showDialog,
        entry,
        goEvenUnsavedData,
        closeDialog,
        saveAndQuit
      }
    }
  })

  function getEventHandler() {
    return function (e: any) {
      // Cancel the event
      e.preventDefault();
      // Chrome requires returnValue to be set
      e.returnValue = '';
    };
  }

  function addEventListener(handler: any) {
    if (process.browser) {
      window.addEventListener('beforeunload', handler);
    }
  }

  function clearEventListener(handler: any) {
    if (process.browser) {
      window.removeEventListener('beforeunload', handler);
    }
  }

</script>

<style scoped>
  .btnActions {
    text-align: right;
  }
</style>
