import {
  Column,
  CreateDateColumn,
  DeleteDateColumn,
  Entity,
  Index,
  JoinColumn,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from 'typeorm';
import { ProgramType } from './program-type.entity';
import { User } from './user.entity';
import { WorkflowStage } from './workflow-stage.entity';
import { WorkflowAction } from './workflow-action.entity';
import { WorkflowConfigurationVariable } from './workflow-configuration-variable.entity';
import { WorkflowLifecycleStatusEnum } from '../enum/workflow-lifecycle-status.enum';

@Entity('workflow_configuration')
@Index('idx_workflow_configuration_program_type_key', ['programTypeKey'])
export class WorkflowConfiguration {

  @PrimaryGeneratedColumn()
  id: number;

  @Column({ name: 'workflow_key', type: 'varchar', length: 100 })
  workflowKey: string;

  @Column({ name: 'workflow_name', type: 'varchar', length: 255 })
  workflowName: string;

  @Column({ name: 'program_type_key', type: 'varchar', length: 100 })
  programTypeKey: string;

  @Column({ name: 'program_type_id', type: 'int', nullable: true })
  programTypeId: number | null;

  @ManyToOne(() => ProgramType, { nullable: true })
  @JoinColumn({ name: 'program_type_id' })
  programType: ProgramType | null;

  @Column({ name: 'workflow_version', type: 'varchar', length: 30 })
  workflowVersion: string;

  @Column({ name: 'lifecycle_status', type: 'enum', enum: WorkflowLifecycleStatusEnum, default: WorkflowLifecycleStatusEnum.ACTIVE })
  lifecycleStatus: WorkflowLifecycleStatusEnum;

  @Column({ type: 'text', nullable: true })
  description: string | null;

  @Column({ name: 'data_query_template', type: 'text', nullable: true })
  dataQueryTemplate: string | null;

  @Column({ name: 'registration_rules', type: 'jsonb', nullable: true })
  registrationRules: Record<string, unknown> | null;

  @Column({ name: 'initial_stage', type: 'jsonb', nullable: true })
  initialStage: Record<string, unknown> | null;

  @Column({ type: 'jsonb', nullable: true })
  metadata: Record<string, unknown> | null;

  @OneToMany(() => WorkflowStage, stage => stage.workflowConfiguration)
  stages: WorkflowStage[];

  @OneToMany(() => WorkflowAction, action => action.workflowConfiguration)
  actions: WorkflowAction[];

  @OneToMany(() => WorkflowConfigurationVariable, wcv => wcv.workflowConfiguration)
  variables: WorkflowConfigurationVariable[];

  @CreateDateColumn({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
  createdAt: Date;

  @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP' })
  updatedAt: Date;

  @DeleteDateColumn({ name: 'deleted_at', type: 'timestamptz', nullable: true })
  deletedAt: Date | null;

  @Column({ name: 'created_by', type: 'int', nullable: true })
  createdById: number | null;

  @Column({ name: 'updated_by', type: 'int', nullable: true })
  updatedById: number | null;

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'created_by' })
  createdBy: User | null;

  @ManyToOne(() => User, { nullable: true })
  @JoinColumn({ name: 'updated_by' })
  updatedBy: User | null;

  constructor(partial: Partial<WorkflowConfiguration>) {
    Object.assign(this, partial);
  }
}
