import * as _ from 'lodash'
import BaseNormalizer from '~/services/serializer/normalizer/baseNormalizer'
import {AnyJson, DataPersisterArgs} from '~/types/interfaces'
import { QUERY_TYPE } from '~/types/enums'
import { repositoryHelper } from '~/services/store/repository'
import { Item } from '@vuex-orm/core'
import {queryHelper} from "~/services/store/query";
import {$objectProperties} from "~/services/utils/objectProperties";

/**
 * @category Services/serializer/normalizer
 * @class Model
 * Classe assurant la normalization d'un Model vers un fichier JSON
 */
class Model extends BaseNormalizer {
  static support (type: QUERY_TYPE): boolean {
    return type === QUERY_TYPE.MODEL
  }

  /**
   * Récupération de l'Item souhaité puis transformation en JSON
   * @param {DataPersisterArgs} args
   * @return {any} réponse
   */
  public static normalize (args: DataPersisterArgs): any {
    if (!args.model) {
      throw new Error('*args* has no model attribute')
    }

    let item:Item = null
    const itemId = args.idTemp ? args.idTemp : args.id

    if(args.query){
      item = queryHelper.getItem(args.query, itemId)
    }else{
      item = repositoryHelper.findItemFromModel(args.model, itemId)
    }

    if (!item || typeof item === 'undefined') {
      throw new Error('Item not found')
    }

    let data = item.$toJson()

    if(Model.isPostQuery(args)) data = Model.sanitizeBeforePost(data, args.query ? args.query.getAllRelations() : [])

    return _.omit(data, 'originalState')
  }

  /**
   * Return true si on est dans un POST
   * @param args
   */
  public static isPostQuery(args: DataPersisterArgs): boolean{
    return args.idTemp
  }

  /**
   * Opération de nettoyage avant un POST
   * @param data
   * @param relations
   */
  public static sanitizeBeforePost(data:AnyJson, relations: Array<string>): AnyJson{
    if(relations){
      data = $objectProperties.cloneAndFlatten(data)
      for(const relation of relations){
        delete data[`${relation}.id`]
        delete data[`${relation}.@id`]
      }
      data = $objectProperties.cloneAndNest(data)
    }

    delete data.id
    return data
  }
}
export default Model
