import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
import { In } from 'typeorm'

import { Notification } from './notification'
import { NewNotification, NotificationPatch } from './notification-type'

@Resolver(Notification)
export class NotificationMutation {
  @Directive('@transaction')
  @Mutation(returns => Notification, { description: 'To create new Notification' })
  async createNotification(
    @Arg('notification') notification: NewNotification,
    @Ctx() context: ResolverContext
  ): Promise<Notification> {
    const { domain, user, tx } = context.state

    return await tx.getRepository(Notification).save({
      ...notification,
      domain,
      creator: user,
      updater: user
    })
  }

  @Directive('@transaction')
  @Mutation(returns => Notification, { description: 'To modify Notification information' })
  async updateNotification(
    @Arg('id') id: string,
    @Arg('patch') patch: NotificationPatch,
    @Ctx() context: ResolverContext
  ): Promise<Notification> {
    const { domain, user, tx } = context.state

    const repository = tx.getRepository(Notification)
    const notification = await repository.findOne({
      where: { domain: { id: domain.id }, id }
    })

    const result = await repository.save({
      ...notification,
      ...patch,
      updater: user
    })

    return result
  }

  @Directive('@transaction')
  @Mutation(returns => [Notification], { description: "To modify multiple Notificationes' information" })
  async updateMultipleNotification(
    @Arg('patches', type => [NotificationPatch]) patches: NotificationPatch[],
    @Ctx() context: ResolverContext
  ): Promise<Notification[]> {
    const { domain, user, tx } = context.state

    let results = []
    const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
    const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
    const notificationRepo = tx.getRepository(Notification)

    if (_createRecords.length > 0) {
      for (let i = 0; i < _createRecords.length; i++) {
        const newRecord = _createRecords[i]

        const result = await notificationRepo.save({
          ...newRecord,
          domain,
          creator: user,
          updater: user
        })

        results.push({ ...result, cuFlag: '+' })
      }
    }

    if (_updateRecords.length > 0) {
      for (let i = 0; i < _updateRecords.length; i++) {
        const updateRecord = _updateRecords[i]
        const notification = await notificationRepo.findOneBy({ id: updateRecord.id })

        const result = await notificationRepo.save({
          ...notification,
          ...updateRecord,
          updater: user
        })

        results.push({ ...result, cuFlag: 'M' })
      }
    }

    return results
  }

  @Directive('@transaction')
  @Mutation(returns => Boolean, { description: 'To delete Notification' })
  async deleteNotification(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {
    const { domain, tx } = context.state

    await tx.getRepository(Notification).delete({ domain: { id: domain.id }, id })

    return true
  }

  @Directive('@transaction')
  @Mutation(returns => Boolean, { description: 'To delete multiple Notificationes' })
  async deleteNotificationes(
    @Arg('ids', type => [String]) ids: string[],
    @Ctx() context: ResolverContext
  ): Promise<boolean> {
    const { domain, tx } = context.state

    await tx.getRepository(Notification).delete({
      domain: { id: domain.id },
      id: In(ids)
    })

    return true
  }
}
