import {AnyJson, AnyStore} from '~/types/interfaces'
import {computed, ComputedRef} from "@nuxtjs/composition-api";
import {Route} from "vue-router";
import {FORM_STATUS, SUBMIT_TYPE} from "~/types/enums";

/**
 * @category composables/form
 * @param store
 * Composable pour gérer l'apparition de message si le formulaire est dirty
 */
export function useForm(store: AnyStore){

  const handler: any = getEventHandler()

  const readonly: ComputedRef<boolean> = computed(() => {
    return store.state.form.readonly
  })

  /**
   * définit le formulaire comme Dirty (modifié)
   */
  function markAsDirty () {
    store.commit('form/setDirty', true)
    if (process.browser) {
      window.addEventListener('beforeunload', handler)
    }
  }

  /**
   * Définit le formulaire comme non dirty (non modifié)
   */
  function markAsNotDirty () {
    store.commit('form/setDirty', false)
    if (process.browser) {
      window.removeEventListener('beforeunload', handler)
    }
  }

  /**
   * Action Sauvegarder qui redirige vers la page d'edit si on est en mode create
   * @param route
   * @param id
   * @param router
   */
  function save(route: Route, id: number, router: any){
    if(store.state.form.formStatus === FORM_STATUS.CREATE){
      route.path += id
      router.push(route)
    }
  }

  /**
   * Action sauvegarder et route suivante qui redirige vers une route
   * @param route
   * @param router
   */
  function saveAndGoTo(route: Route, router: any){
    router.push(route)
  }

  /**
   * Factory des fonction permettant d'assurer l'étape suivant à la soumission d'un formulaire
   * @param args
   * @param response
   * @param router
   */
  function nextStepFactory(args: any, response: AnyJson, router: any){
    const factory: AnyJson = {}
    factory[SUBMIT_TYPE.SAVE] = () => save(args, response.id, router)
    factory[SUBMIT_TYPE.SAVE_AND_BACK] = () => saveAndGoTo(args, router)
    return factory
  }

  return {
    markAsDirty,
    markAsNotDirty,
    nextStepFactory,
    readonly
  }
}

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