import Vue from 'vue'
import { ref } from '@vue/composition-api'
import * as jot from 'jot'
import gql from 'graphql-tag'

export const useEditDialog = (props, context, query, fields, lists = {}) => {
  const doc = ref(null)
  const data = ref({})

  const coll = query.match(/^\s*[^{(\s]*/)?.[0]?.replace(/^\s/, '')

  context.parent.$apollo.addSmartQuery(coll, {
    query: gql`query($id: UUID!) { ${query} }`,
    variables () {
      return {
        id: !props.value || props.id
      }
    },
    skip () {
      return !props.value || !props.id
    },
    update (d) {
      _update(d[coll])
    }
  })

  const addfields = () => {
    for (const field of fields) {
      const p = field.split('.')

      let d = data.value
      for (const i in p) {
        if (!d[p[i]]) {
          if (i < p.length - 1) {
            Vue.set(d, p[i], {})
          } else {
            Vue.set(d, p[i], '')
          }
        }
        d = d[p[i]]
      }
    }
  }

  addfields()

  const removeimg = () => {
    for (const field of fields) {
      if (context.refs[field] && context?.refs[field]?.$vnode?.tag?.indexOf('VImageInput') !== -1) {
        context.refs[field].internalImageData = ''
      }
    }
  }

  /* let arrays = {}

  for (const name in lists) {
    arrays = { ...arrays, ...useEditList(props, context, doc, data, name, lists[name]) }
  } */

  const del = async () => {
    if (doc?.value?._id && await context.root.$children[0].$refs.confirm.open('Löschen', 'Sind Sie sicher?')) {
      context.parent.$apollo.mutate({
        mutation: gql`mutation($id: UUID!) { ${coll}Delete(id: $id) }`,
        variables: {
          id: doc?.value?._id
        }
      })
      close()
    }
  }

  const close = () => {
    context.emit('input', false)

    Vue.set(doc, 'value', null)
    Vue.set(data, 'value', {})
    addfields()
    removeimg()

    const self = context?.parent?.$children?.find(e => e?.$el?._prevClass === 'v-dialog__container')
    if (self && typeof self.onClose === 'function') self.onClose()
  }

  const save = () => {
    const self = context?.parent?.$children?.find(e => e?.$el?._prevClass === 'v-dialog__container')

    let func = null

    if (self.data._id) {
      if (!self && typeof self.update !== 'function') return
      func = self.update
    } else {
      if (!self && typeof self.create !== 'function') return
      func = self.create
    }

    let { mutation, variables } = func()

    if (!mutation) return
    if (!variables) variables = {}

    if (self.data._id) {
      variables.id = self.data._id
    }

    for (const field of fields) {
      if (variables[field] === undefined && self.data[field] !== self.doc?.[field]) {
        variables[field] = self.data[field]
      }
    }

    context.parent.$apollo.mutate({
      mutation: gql(mutation),
      variables
    }).catch(e => {
      context.root.$store.commit('OPEN_SNACKBAR', e)
    })

    if (self && typeof self.onSave === 'function') self.onSave()
    close()
  }

  /* const savelist = async (id, l, listdata) => {
    let subcoll = l.split('')
    subcoll[0] = l[0].toUpperCase()
    subcoll = subcoll.join('')

    listdata = listdata.map(d => {
      const neu = {}
      for (const k of lists[l]) {
        neu[k] = d[k]
      }
      return neu
    })

    const up = `mutation { Update${coll}${subcoll}(id: "${id}", ${l}: ${JSON.stringify(listdata).replace(/"([^"]+)":/g, '$1:')}) ${q} }`
    console.log(up)
    return context.parent.$apollo.mutate({
      mutation: gql(up),
    })
  }

  watch(props, () => {
    if (props.id && props.value) {
      removeimg()
      addfields()
      const self = context?.parent?.$children?.find(e => e?.$el?._prevClass === 'v-dialog__container')
      if (self && typeof self.onInit === 'function') self.onInit()
    } else if (props.id) {
      removeimg()
      addfields()
    }
    if (!props.value) {
      close()
    }
  }) */

  const _update = (neu) => {
    if (doc.value === null) {
      Vue.set(doc, 'value', neu)
      Vue.set(data, 'value', JSON.parse(JSON.stringify(neu)))
      addfields()
    } else {
      const user1 = jot.diff(doc.value, neu)
      const user2 = jot.diff(doc.value, data.value)
      const user3 = user2.rebase(user1, { document: doc.value })
      Vue.set(data, 'value', user1.compose(user3).apply(JSON.parse(JSON.stringify(doc.value))))
      Vue.set(doc, 'value', JSON.parse(JSON.stringify(neu)))
      addfields()
    }
  }

  // return { doc, data, del, close, save, ...arrays, [coll]: apollodoc }

  return { doc, data, close, del, save }
}
