import { Domain, ScalarAny } from '@things-factory/shell'
import { User } from '@things-factory/auth-base'
import { ObjectType, Field, InputType, Int, Float, ID, registerEnumType } from 'type-graphql'

//   input JointsInput {
//     j1: Float
//     j2: Float
//     j3: Float
//     j4: Float
//     j5: Float
//     j6: Float
//   }
@InputType()
export class JointsInput {
  @Field(type => Float)
  j1: number

  @Field(type => Float)
  j2: number

  @Field(type => Float)
  j3: number

  @Field(type => Float)
  j4: number

  @Field(type => Float)
  j5: number

  @Field(type => Float)
  j6: number
}

//   input PoseInput {
//     x: Float
//     y: Float
//     z: Float
//     u: Float
//     v: Float
//     w: Float
//   }
@InputType()
export class PoseInput {
  @Field(type => Float)
  x: number

  @Field(type => Float)
  y: number

  @Field(type => Float)
  z: number

  @Field(type => Float)
  u: number

  @Field(type => Float)
  v: number

  @Field(type => Float)
  w: number
}

// type Pose {
//   x: Float
//   y: Float
//   z: Float
//   u: Float
//   v: Float
//   w: Float
// }
@ObjectType()
export class Pose {
  @Field(type => Float, { nullable: true })
  x: number

  @Field(type => Float, { nullable: true })
  y: number

  @Field(type => Float, { nullable: true })
  z: number

  @Field(type => Float, { nullable: true })
  u: number

  @Field(type => Float, { nullable: true })
  v: number

  @Field(type => Float, { nullable: true })
  w: number
}

// type Joints {
//   j1: Float
//   j2: Float
//   j3: Float
//   j4: Float
//   j5: Float
//   j6: Float
// }
@ObjectType()
export class Joints {
  @Field(type => Float)
  j1: number

  @Field(type => Float)
  j2: number

  @Field(type => Float)
  j3: number

  @Field(type => Float)
  j4: number

  @Field(type => Float)
  j5: number

  @Field(type => Float)
  j6: number
}

// type PixelPoint {
//   x: Int
//   y: Int
// }
@ObjectType()
export class PixelPoint {
  @Field(type => Int)
  x: number

  @Field(type => Int)
  y: number
}

// type Region {
//   lt: PixelPoint
//   rb: PixelPoint
// }
@ObjectType()
export class Region {
  @Field(type => PixelPoint)
  lt: PixelPoint

  @Field(type => PixelPoint)
  rb: PixelPoint
}

// type ROI {
//   id: String
//   region: Region
// }
@ObjectType()
export class ROI {
  @Field()
  id: string

  @Field(type => Region)
  region: Region
}

// type Matrix {
//   rows: Int
//   columns: Int
//   data: [Float]
// }
@ObjectType()
export class Matrix {
  @Field(type => Int)
  rows: number

  @Field(type => Int)
  columns: number

  @Field(type => [Float])
  data: number[]
}

// type CameraParameter {
//   distortionCoefficient: [Float]
//   cameraMatrix: Matrix
// }
@ObjectType()
export class CameraParameter {
  @Field(type => [Float])
  distortionCoefficient: number[]

  @Field(type => Matrix)
  cameraMatrix: Matrix
}

// type HandEyeConfig {
//   mode: String
//   autoTotalIter: Int
//   autoMoveXyz: Float
//   autoMoveUvw: Float
// }
@ObjectType()
export class HandEyeConfig {
  @Field({ nullable: true })
  mode: string

  @Field(type => Int, { nullable: true })
  autoTotalIter: number

  @Field(type => Float, { nullable: true })
  autoMoveXyz: number

  @Field(type => Float, { nullable: true })
  autoMoveUvw: number
}

// export const RobotArmStatus = gql`
//   type RobotArmStatus {
//     running: Boolean
//     ready: Boolean
//     busy: Boolean
//     moveFinished: Boolean
//     home: Boolean
//     zero: Boolean
//     teachingMode: Boolean
//     error: Boolean
//     collided: Boolean
//     emergency: Boolean
//   }
// `
@ObjectType()
export class RobotArmStatus {
  @Field()
  running: boolean

  @Field()
  ready: boolean

  @Field()
  busy: boolean

  @Field()
  moveFinished: boolean

  @Field()
  home: boolean

  @Field()
  zero: boolean

  @Field()
  teachingMode: boolean

  @Field()
  error: boolean

  @Field()
  collided: boolean

  @Field()
  emergency: boolean
}

// export const RobotArm = gql`
//   type RobotArm {
//     id: String
//     name: String
//     domain: Domain
//     description: String
//     type: String
//     endpoint: String
//     active: Boolean
//     params: Object
//     markerOffset: Pose
//     toolOffset: Pose
//     updater: User
//     creator: User
//     updatedAt: String
//     createdAt: String
//   }
// `
@ObjectType()
export class RobotArm {
  @Field(type => ID, { nullable: true })
  id?: string

  @Field()
  name: string

  @Field(type => Domain)
  domain: Domain

  @Field({ nullable: true })
  description: string

  @Field({ nullable: true })
  type: string

  @Field({ nullable: true })
  endpoint: string

  @Field({ nullable: true })
  active: boolean

  // TODO: check object
  @Field(type => ScalarAny, { nullable: true })
  params: object

  @Field(type => Pose, { nullable: true })
  markerOffset: Pose

  @Field(type => Pose, { nullable: true })
  toolOffset: Pose

  @Field(type => User, { nullable: true })
  updater: User

  @Field(type => User, { nullable: true })
  creator: User

  @Field({ nullable: true })
  updatedAt: string

  @Field({ nullable: true })
  createdAt: string
}

// type RobotArmList {
//   items: [RobotArm]
//   total: Int
// }
@ObjectType()
export class RobotArmList {
  @Field(type => [RobotArm])
  items: RobotArm[]

  @Field(type => Int)
  total: number
}

// @InputType()
// export class NewRobotArm {
//   @Field()
//   name: string

//   @Field({ nullable: true })
//   description?: string

//   @Field(type => RobotArmStatus, { nullable: true })
//   state?: RobotArmStatus

//   @Field({ nullable: true })
//   active?: boolean

//   @Field({ nullable: true })
//   params?: string
// }

// @InputType()
// export class RobotArmPatch {
//   @Field(type => ID, { nullable: true })
//   id?: string

//   @Field({ nullable: true })
//   name?: string

//   @Field({ nullable: true })
//   description?: string

//   @Field(type => RobotArmStatus, { nullable: true })
//   state?: RobotArmStatus

//   @Field({ nullable: true })
//   active?: boolean

//   @Field()
//   cuFlag: string
// }

// @ObjectType()
// export class RobotArmList {
//   @Field(type => [RobotArm])
//   items: RobotArm[]

//   @Field(type => Int)
//   total: number
// }
