import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  Index,
  ManyToOne,
  JoinColumn,
} from 'typeorm';
import { CommunicationTypeEnum } from '../enum/communication-type.enum';

import { CommunicationCategoryEnum } from '../enum/communication-category.enum';
import { TemplateUsageTypeEnum } from '../enum/template-usage-type.enum';
import { CommunicationTemplateAccessKeyEnum } from '../enum/communication-template-access-key.enum';
import { CommunicationStepEnum } from '../enum/communication-step.enum';
import { ProgramType } from './program-type.entity';

/**
 * Master Communication Templates Entity
 * Stores reusable template definitions with category and merge info mappings
 */
@Entity('communication_templates_master')
export class CommunicationTemplatesMaster {
  @PrimaryGeneratedColumn('increment', { type: 'bigint' })
  id: number;

  @Column({ name: 'template_key', type: 'varchar', length: 255, nullable: false })
  templateKey: string;

  /**
   * Template Access Key - Common key across program types for same purpose
   * e.g., REGISTRATION_COMPLETED for both HDB and ENT
   */
  @Column({
    name: 'template_access_key',
    type: 'enum',
    enum: CommunicationTemplateAccessKeyEnum,
    nullable: false,
  })
  templateAccessKey: CommunicationTemplateAccessKeyEnum;

  @Column({
    name: 'template_name',
    type: 'varchar',
    length: 255,
    nullable: false,
  })
  templateName: string;

  @Column({
    name: 'template_type',
    type: 'enum',
    enum: CommunicationTypeEnum,
    nullable: false,
  })
  templateType: CommunicationTypeEnum;

  /**
   * Production template ID from provider (Zepto/WATI)
   */
  @Column({
    name: 'template_id',
    type: 'varchar',
    length: 500,
    nullable: false,
  })
  templateId: string;

  /**
   * Sandbox/development template ID from provider
   * Used in dev/staging environments
   */
  @Column({
    name: 'sandbox_template_id',
    type: 'varchar',
    length: 500,
    nullable: true,
  })
  sandboxTemplateId: string;

  /**
   * Category for template classification and filtering
   */
  @Column({
    name: 'category',
    type: 'enum',
    enum: CommunicationCategoryEnum,
    nullable: true,
  })
  category: CommunicationCategoryEnum;

  /**
   * Template usage type - general or bulk email
   * Used for bulk cloning operations
   */
  @Column({
    name: 'template_usage_type',
    type: 'enum',
    enum: TemplateUsageTypeEnum,
    nullable: false,
    default: TemplateUsageTypeEnum.GENERAL,
  })
  templateUsageType: TemplateUsageTypeEnum;

  /**
   * Program Type ID - links template to specific program type
   */
  @Column({ name: 'program_type_id', type: 'int', nullable: true })
  programTypeId: number;

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

  /**
   * MergeFieldMap stores the mapping information as JSON array:
   * Example:
   * [
   *   {
   *     keyName: "reg_fullname",
   *     sourceTable: "program_registration",
   *     sourceColumn: "full_name",
   *     dataType: "string",
   *     formatType: null,
   *     isNullable: false,
   *     defaultValue: "",
   *     description: "Registrant's full name",
   *     isPerRecipient: false
   *   },
   *   ...
   * ]
   */
  @Column({
    name: 'merge_field_map',
    type: 'jsonb',
    nullable: true,
    default: [],
  })
  mergeFieldMap: Array<{
    keyName: string;
    sourceTable: string;
    sourceColumn: string;
    dataType: string;
    formatType?: string;
    isNullable: boolean;
    defaultValue?: string;
    description?: string;
    isPerRecipient?: boolean;
  }>;

  @Column({ name: 'display_order', type: 'int', nullable: true })
  displayOrder: number;

  /**
   * Lifecycle step this template fires on (CommunicationStepEnum). Stored as varchar.
   * NULL for legacy access keys that don't map to a step.
   */
  @Column({ name: 'step', type: 'varchar', length: 64, nullable: true })
  step: CommunicationStepEnum | null;

  @Column({ name: 'subject', type: 'varchar', length: 500, nullable: true })
  subject: string | null;

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

  /**
   * When true, this template auto-enables on new programs of its program_type.
   */
  @Column({ name: 'is_default', type: 'boolean', default: true })
  isDefault: boolean;

  @Column({
    name: 'is_active',
    type: 'boolean',
    default: true,
  })
  isActive: boolean;

  @Column({ name: 'created_by', type: 'bigint', nullable: true })
  createdBy: number;

  @Column({ name: 'updated_by', type: 'bigint', nullable: true })
  updatedBy: number;

  @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;

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