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

import {
  HistoryActionColumn,
  HistoryActionType,
  HistoryEntityInterface,
  HistoryOriginalIdColumn
} from '@operato/typeorm-history'
import { Role, User } from '@things-factory/auth-base'
import { config } from '@things-factory/env'
import { Domain } from '@things-factory/shell'

import { NotificationRule, NotificationRuleStatus, RecipientItem } from './notification-rule'

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

@Entity()
@Index(
  'ix_notification-rule_history_0',
  (notificationRuleHistory: NotificationRuleHistory) => [
    notificationRuleHistory.originalId,
    notificationRuleHistory.version
  ],
  { unique: true }
)
@Index(
  'ix_notification-rule_history_1',
  (notificationRuleHistory: NotificationRuleHistory) => [
    notificationRuleHistory.domain,
    notificationRuleHistory.originalId,
    notificationRuleHistory.version
  ],
  { unique: true }
)
@ObjectType({ description: 'History Entity of NotificationRule' })
export class NotificationRuleHistory implements HistoryEntityInterface<NotificationRule> {
  @PrimaryGeneratedColumn('uuid')
  @Field(type => ID)
  readonly id: string

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

  @ManyToOne(type => Domain)
  @Field(type => Domain)
  domain?: Domain

  @RelationId((notificationRule: NotificationRule) => notificationRule.domain)
  domainId?: string

  @Column()
  @Field()
  name: string

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

  @Column({ nullable: true })
  @Field({ nullable: true })
  state?: NotificationRuleStatus

  @Column({ nullable: true })
  @Field({ nullable: true })
  title: string

  @Column({ nullable: true })
  @Field({ nullable: true })
  body: string

  @Column({ nullable: true })
  @Field({ nullable: true })
  url: string

  @Column({ nullable: true })
  @Field({ nullable: true })
  thumbnail: string

  @Column({ nullable: true })
  @Field({ nullable: true })
  channels: string

  @Column('simple-json', { nullable: true })
  @Field(type => [RecipientItem], { nullable: true, description: 'notification recipients.' })
  recipients: string

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

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

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

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

  @RelationId((notificationRule: NotificationRule) => notificationRule.creator)
  creatorId?: string

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

  @RelationId((notificationRule: NotificationRule) => notificationRule.updater)
  updaterId?: string

  @HistoryOriginalIdColumn()
  public originalId!: string

  @HistoryActionColumn({
    nullable: false,
    type:
      DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
        ? 'enum'
        : DATABASE_TYPE == 'oracle'
          ? 'varchar2'
          : DATABASE_TYPE == 'mssql'
            ? 'nvarchar'
            : 'varchar',
    enum:
      DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
        ? HistoryActionType
        : undefined,
    length: DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb' ? undefined : 10
  })
  public action!: HistoryActionType
}
