import { Arg, Ctx, Query, Resolver } from 'type-graphql'
import { getRepository } from 'typeorm'
import { v4 as uuidv4 } from 'uuid'

import { Board } from '@things-factory/board-service'
import { checkTarget, doSomething, getPermission } from '@things-factory/operato-license-checker'

import { LicenseError } from '../../errors/license-error'
import { DomainSecret } from '../domain-secret/domain-secret'
import { BoardSecret } from './board-secret'

const debug = require('debug')('things-factory:operato-board:board-resolver')

@Resolver(Board)
export class BoardResolver {
  @Query(returns => [String], { description: 'Board Usage Permissions' })
  boardPermissions(@Ctx() context: any): string[] {
    return (getPermission('Permissions For Board Usage') || 'Modeller, Viewer').split(',').map(p => p.trim())
  }

  @Query(returns => Board, { description: 'To fetch a board' })
  async board(@Arg('id') id: string, @Ctx() context: any): Promise<Board> {
    const { domain } = context.state

    var board = await getRepository(Board).findOne({
      where: { domain, id }
    })
    if (domain) {
      // 1. check domainSecret is over limit quantity or not
      var count =
        (await getRepository(DomainSecret)
          .manager.createQueryBuilder()
          .select('board')
          .from(DomainSecret, 'secret')
          .where('id = :domainId', { domainId: domain.id })
          .getCount()) + 1

      if (!checkTarget(count)) {
        throw new LicenseError({
          errorCode: context.t(LicenseError.ERROR_CODES.OVER_LIMIT)
        })
      } else {
        var domainSecret: DomainSecret = await getRepository(DomainSecret).findOne({
          where: { domain: domain }
        })
        // 2. if there's no domainSecret then create it
        if (!domainSecret) {
          var domainSecret: DomainSecret = new DomainSecret()
          domainSecret.id = uuidv4()
          domainSecret.domain = domain
          var hash = doSomething({ secId: domainSecret.id, id: domain.id })
          domainSecret.secret = hash

          await getRepository(DomainSecret).save(domainSecret)
          // 3. if there's domainSecret then check it
        } else {
          var domainRepo = getRepository(DomainSecret)
          var domainSecret: DomainSecret = await domainRepo.findOne({
            where: { domain: domain }
          })
          if (domainSecret) {
            var hash = doSomething({ secId: domainSecret.id, id: domain.id })
            if (domainSecret.secret !== hash) {
              throw new LicenseError({
                errorCode: context.t(LicenseError.ERROR_CODES.VERIFICATION_ERROR)
              })
            }
          } else {
            throw new LicenseError({
              errorCode: context.t(LicenseError.ERROR_CODES.VERIFICATION_ERROR)
            })
          }
        }
      }
    }
    if (board) {
      // 1. check boardSecret is over limit quantity or not
      var count =
        (await getRepository(BoardSecret)
          .manager.createQueryBuilder()
          .select('board')
          .from(BoardSecret, 'secret')
          .where('domain_id = :domainId', { domainId: domain.id })
          .getCount()) + 1

      if (!checkTarget(count)) {
        throw new LicenseError({
          errorCode: context.t(LicenseError.ERROR_CODES.OVER_LIMIT)
        })
      } else {
        var boardSecret: BoardSecret = await getRepository(BoardSecret).findOne({
          where: { targetId: id }
        })
        // 2. if there's no boardSecret then create it
        if (!boardSecret) {
          var boardSecret: BoardSecret = new BoardSecret()
          boardSecret.id = uuidv4()
          boardSecret.targetId = id
          boardSecret.targetType = 'board'
          boardSecret.domain = domain

          var hash = doSomething({ secId: boardSecret.id, id: id })
          boardSecret.secret = hash

          await getRepository(BoardSecret).save(boardSecret)
          // 3. if there's boardSecret then check it
        } else {
          var repogitory = getRepository(BoardSecret)
          var boardSecret: BoardSecret = await repogitory.findOne({
            where: { targetId: id }
          })
          if (boardSecret) {
            var hash = doSomething({ secId: boardSecret.id, id: id })
            if (boardSecret.secret !== hash) {
              throw new LicenseError({
                errorCode: context.t(LicenseError.ERROR_CODES.VERIFICATION_ERROR)
              })
            }
          } else {
            throw new LicenseError({
              errorCode: context.t(LicenseError.ERROR_CODES.VERIFICATION_ERROR)
            })
          }
        }
      }
    }

    return board
  }
}
