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

import { Domain, ScalarObject } from '@things-factory/shell'
import { User } from '@things-factory/auth-base'
import { config } from '@things-factory/env'

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

export enum ProcessTemplateStatus {
  DRAFT = 'DRAFT',
  RELEASED = 'RELEASED'
}

registerEnumType(ProcessTemplateStatus, {
  name: 'ProcessTemplateStatus',
  description: 'state enumeration of a processTemplate'
})

@Entity()
@Index('ix_process_template_0', (processTemplate: ProcessTemplate) => [processTemplate.domain, processTemplate.name], {
  unique: true
})
@ObjectType({ description: 'Entity for ProcessTemplate' })
export class ProcessTemplate {
  @PrimaryGeneratedColumn('uuid')
  @Field(type => ID)
  readonly id: string

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

  @RelationId((processTemplate: ProcessTemplate) => processTemplate.domain)
  domainId?: string

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

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

  @Column('simple-json', { nullable: true, default: null })
  @Field(type => ScalarObject, { nullable: true })
  tags?: string[]

  @Column({ nullable: true, default: 'private' })
  @Field({ nullable: true })
  visibility?: string // 'private' | 'public' | 'domain'

  @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

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

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

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

  @RelationId((processTemplate: ProcessTemplate) => processTemplate.creator)
  creatorId?: string

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

  @RelationId((processTemplate: ProcessTemplate) => processTemplate.updater)
  updaterId?: string
}
