import { GraphQLScalarType, Kind, ValueNode } from 'graphql'

export const JSONScalar: GraphQLScalarType = new GraphQLScalarType({
  name: 'JSON',
  serialize: (value: any): any => value,
  parseValue: (value: any): any => value,
  parseLiteral: (ast: ValueNode): any => {
    switch (ast.kind) {
      case Kind.STRING:
      case Kind.BOOLEAN:
        return ast.value
      case Kind.INT:
      case Kind.FLOAT:
        return parseFloat(ast.value)
      case Kind.OBJECT:
        return ast.fields.reduce(
          (accumulator, field) => ({
            ...accumulator,
            [field.name.value]: JSONScalar.parseLiteral(field.value),
          }),
          {},
        )
      case Kind.LIST:
        return ast.values.map((n) => JSONScalar.parseLiteral(n))
      default:
        return null
    }
  },
})

export const DateTimeScalar = new GraphQLScalarType({
  name: 'DateTime',
  serialize: (value) => {
    if (value instanceof Date) {
      return value.toISOString()
    }
    return value
  },
  parseValue: (value) => {
    if (typeof value === 'string') {
      return new Date(value)
    }
    return value
  },
  parseLiteral: (ast) => {
    if (ast.kind === Kind.STRING) {
      return new Date(ast.value)
    }
    return null
  },
})
