import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
import { Domain, ListParam } from '@things-factory/shell'
import { TrackingCamera, TrackingCameraList } from './tracking-camera-type'

import { ROBOTICS_OBJECT_TYPES } from '../../controllers/robotics-types'
import { ConnectionManager } from '@things-factory/integration-base'

const debug = require('debug')('aidoop:robotics:tracking-camera-query')

// extend type Query {
//   trackingCameras(filters: [Filter], pagination: Pagination, sortings: [Sorting]): TrackingCameraList
//   trackingCamera(name: String!): TrackingCamera
// }

@Resolver(TrackingCamera)
export class TrackingCameraQuery {
  @Query(returns => TrackingCamera, { description: 'To fetch a tracking camera' })
  async trackingCamera(
    @Arg('name', type => String, { nullable: false }) name: string,
    @Ctx() context: any
  ): Promise<TrackingCamera> {
    const { domain } = context.state

    var connection = ConnectionManager.getConnectionInstanceByName(domain, name)
    if (!connection || connection.discriminator !== ROBOTICS_OBJECT_TYPES.CAMERA) {
      throw Error(`TrackingCamera '${name}' Not Found`)
    }

    var { handEyeConfig, handEyeMatrix, cameraCalibration, rois, camObjOffset, width, height } = connection.params || {}
    var { cameraMatrix, distortionCoefficient } = cameraCalibration || {}

    return {
      ...connection,
      cameraMatrix,
      distortionCoefficient,
      handEyeConfig,
      handEyeMatrix,
      rois,
      camObjOffset,
      width,
      height
    }
  }

  @Query(returns => TrackingCameraList, { description: 'To fetch multiple tracking cameras' })
  async trackingCameras(@Args() params: ListParam, @Ctx() context: any): Promise<TrackingCameraList> {
    const { domain } = context.state

    var items = Object.keys(ConnectionManager.getConnectionInstances(domain))
      .map(name => ConnectionManager.getConnectionInstanceByName(domain, name))
      .filter(connection => connection.discriminator == ROBOTICS_OBJECT_TYPES.CAMERA)
      .map(connection => {
        var { handEyeConfig, handEyeMatrix, cameraCalibration, rois, camObjOffset, width, height } =
          connection.params || {}
        var { cameraMatrix, distortionCoefficient } = cameraCalibration || {}

        return {
          ...connection,
          cameraMatrix,
          distortionCoefficient,
          handEyeConfig,
          handEyeMatrix,
          rois,
          camObjOffset,
          width,
          height
        }
      })

    return {
      items,
      total: items.length
    }
  }

  @FieldResolver(type => Domain)
  async baseRobotArm(@Root() trackingCamera: TrackingCamera) {
    const { domain } = trackingCamera
    const { baseRobotArm } = trackingCamera.params || {}

    var baseRobotArmObj = ConnectionManager.getConnectionInstanceByName(domain, baseRobotArm)
    if (!baseRobotArmObj || baseRobotArmObj.discriminator !== ROBOTICS_OBJECT_TYPES.ROBOT_ARM) {
      return
    }

    return baseRobotArmObj
  }
}
