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

import { Process } from '../process/process'
import { ProcessGroup } from './process-group'
import { ProcessGroupPatch, NewProcessGroup } from './process-group-type'

@Resolver(ProcessGroup)
export class ProcessGroupMutation {
  @Directive('@transaction')
  @Mutation(returns => ProcessGroup, { nullable: true, description: 'To create new ProcessGroup' })
  async createProcessGroup(
    @Arg('group') group: NewProcessGroup,
    @Ctx() context: ResolverContext
  ): Promise<ProcessGroup> {
    const { domain, user, tx } = context.state

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

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

    const group = await repository.findOneBy({ domain: { id: domain.id }, id })

    return await repository.save({
      ...group,
      ...patch,
      updater: user
    })
  }

  @Directive('@transaction')
  @Mutation(returns => ProcessGroup, { description: 'To make the process to join the group' })
  async joinProcessGroup(
    @Arg('id') id: string,
    @Arg('processIds', type => [String]) processIds: string[],
    @Ctx() context: ResolverContext
  ) {
    const { domain, tx } = context.state
    const repository = tx.getRepository(ProcessGroup)
    const group = await repository.findOneBy({ domain: { id: domain.id }, id })

    const processRepository = tx.getRepository(Process)

    await processIds.forEach(async processId => {
      let process = await processRepository.findOneBy({ domain: { id: domain.id }, id: processId })
      process.group = group
      await processRepository.save(process)
    })

    return await repository.findOne({
      where: { domain: { id: domain.id }, id },
      relations: ['processes']
    })
  }

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

    const repository = tx.getRepository(ProcessGroup)

    /* TODO - 그룹에 소속된 보드가 있는 경우에는 그룹을 지워서는 안된다. */
    const group = await repository.findOneBy({
      domain: { id: domain.id },
      id
    })

    await repository.delete(id)
    return true
  }
}
