import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
import { Domain, getQueryBuilderFromListParams, getRepository, ListParam, ScalarDate } from '@things-factory/shell'
import { User } from '@things-factory/auth-base'
import { Notification } from './notification'
import { NotificationList } from './notification-type'

@Resolver(Notification)
export class NotificationQuery {
  @Query(returns => Notification!, { nullable: true, description: 'To fetch a Notification' })
  async notification(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Notification> {
    const { domain } = context.state

    return await getRepository(Notification).findOne({
      where: { domain: { id: domain.id }, id }
    })
  }

  @Query(returns => NotificationList, { description: 'To fetch multiple Notificationes' })
  async notificationes(
    @Args(type => ListParam) params: ListParam,
    @Ctx() context: ResolverContext
  ): Promise<NotificationList> {
    const { domain } = context.state

    const queryBuilder = getQueryBuilderFromListParams({
      domain,
      params,
      repository: await getRepository(Notification),
      searchables: ['title', 'body']
    })

    const [items, total] = await queryBuilder.getManyAndCount()

    return { items, total }
  }

  @Query(returns => NotificationList, { description: 'To fetch my notifications' })
  async myNotifications(
    @Args(type => ListParam) params: ListParam,
    @Ctx() context: ResolverContext
  ): Promise<NotificationList> {
    const { domain, user } = context.state

    const queryBuilder = getQueryBuilderFromListParams({
      domain,
      params,
      alias: 'nb',
      repository: await getRepository(Notification),
      searchables: ['title', 'body']
    }).andWhere('nb.owner = :user', { user: user.id })

    const [items, total] = await queryBuilder.getManyAndCount()

    return { items, total }
  }

  @FieldResolver(type => User)
  async owner(@Root() notification: Notification): Promise<User> {
    return notification.ownerId && (await getRepository(User).findOneBy({ id: notification.ownerId }))
  }

  @FieldResolver(type => Domain)
  async domain(@Root() notification: Notification): Promise<Domain> {
    return notification.domainId && (await getRepository(Domain).findOneBy({ id: notification.domainId }))
  }

  @FieldResolver(type => User)
  async updater(@Root() notification: Notification): Promise<User> {
    return notification.updaterId && (await getRepository(User).findOneBy({ id: notification.updaterId }))
  }

  @FieldResolver(type => User)
  async creator(@Root() notification: Notification): Promise<User> {
    return notification.creatorId && (await getRepository(User).findOneBy({ id: notification.creatorId }))
  }
}
