import {
  Column,
  CreateDateColumn,
  Entity,
  Index,
  ManyToOne,
  PrimaryGeneratedColumn,
  RelationId,
  DeleteDateColumn,
  UpdateDateColumn
} from 'typeorm'
import { Field, ID, ObjectType } from 'type-graphql'

import { Domain } from '@things-factory/shell'
import { ProcessGroup } from '../process-group/process-group'
import { User } from '@things-factory/auth-base'
import { config } from '@things-factory/env'

const ORMCONFIG = config.get('ormconfig', {})
const DATABASE_TYPE = ORMCONFIG.type

@Entity()
@Index('ix_process_0', (process: Process) => [process.domain, process.name, process.creator], {
  unique: true,
  where: '"deleted_at" IS NULL'
})
@Index('ix_process_1', (process: Process) => [process.domain, process.group, process.name])
@ObjectType({ description: 'Entity for Integration Process' })
export class Process {
  @PrimaryGeneratedColumn('uuid')
  @Field(type => ID, { nullable: true })
  readonly id?: string

  @Column({ nullable: true, default: 1 })
  @Field({ nullable: true })
  version?: number = 1

  @ManyToOne(type => Domain)
  @Field({ nullable: true })
  domain?: Domain

  @RelationId((process: Process) => process.domain)
  domainId?: string

  @Column()
  @Field()
  name?: string

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

  @Column({ nullable: true, default: 'draft' })
  @Field({ nullable: true })
  state?: 'draft' | 'released'

  @Column({
    nullable: true,
    type:
      DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
        ? 'longtext'
        : DATABASE_TYPE == 'oracle'
        ? 'clob'
        : 'varchar'
  })
  @Field({ nullable: true })
  model?: string

  @Column({
    nullable: true,
    type:
      DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
        ? 'longtext'
        : DATABASE_TYPE == 'oracle'
        ? 'clob'
        : 'varchar'
  })
  @Field({ nullable: true })
  thumbnail?: string

  @ManyToOne(type => ProcessGroup, group => group.processes)
  @Field(type => ProcessGroup, { nullable: true })
  group?: ProcessGroup

  @RelationId((process: Process) => process.group)
  groupId?: string

  @CreateDateColumn()
  @Field({ nullable: true })
  createdAt?: Date

  @UpdateDateColumn()
  @Field({ nullable: true })
  updatedAt?: Date

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

  @RelationId((process: Process) => process.creator)
  creatorId?: string

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

  @RelationId((process: Process) => process.updater)
  updaterId?: string

  @DeleteDateColumn()
  @Field({ nullable: true })
  deletedAt?: Date
}
