// @ts-ignore
import { v4 as uuid } from 'uuid'
import { SubscriptionClient } from 'subscriptions-transport-ws'
import ApolloClient from 'apollo-client'
import VueApollo from 'vue-apollo'
import { defaultDataIdFromObject, InMemoryCache } from 'apollo-cache-inmemory'
// @ts-ignore
import * as Cookie from 'js-cookie'
import { ref } from '@vue/composition-api'
import gql from 'graphql-tag'

export const clientId = uuid()

const server = process.env.NODE_ENV === 'production' ? 'wss://turnenaufzeit.de/gql' : 'ws://localhost:3000/graphql'

const client = new SubscriptionClient(server, {
  reconnect: true,
  connectionParams: () => ({
    clientId,
    token: Cookie.get('token')
  })
})

const graphQL = new ApolloClient({
  // @ts-ignore
  link: client,
  cache: new InMemoryCache({
    dataIdFromObject: object => {
      switch (object.__typename) {
        default: return defaultDataIdFromObject(object)
      }
    }
  }),
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'cache-and-network'
    },
    query: {
      fetchPolicy: 'no-cache'
    }
  }
})

export default new VueApollo({
  defaultClient: graphQL
})

export const useGraphQL = (context: any): any => {
  const connected = ref(client?.client?.readyState === 1)

  client.on('connecting', () => { connected.value = false })
  client.on('connected', () => { connected.value = true })
  client.on('reconnecting', () => { connected.value = false })
  client.on('reconnected', () => { connected.value = true })
  client.on('disconnected', () => { connected.value = false })
  client.on('error', () => { connected.value = false })

  const login = async (email: string, passwort: string) => {
    let query = `login(email: "${email}", passwort: "${passwort}")`
    if (!email || !passwort) {
      query = `login(token: "${Cookie.get('token')}")`
    }

    const { data } = await graphQL.mutate({
      mutation: gql`mutation { ${query} {
        _id
        token
        givenName
        familyName
        adminOf { _id name plz ort }
      }}`
    })

    console.log(data)

    context.root.$store.commit('SET_PROFILE', data.login)

    Cookie.set('token', data?.login?.token, '12h', null, null, null, 'strict')
  }

  return { connected, login }
}
