import { DataTypes, Model, Optional, Sequelize } from 'sequelize';

export interface CampaignAttributes extends Optional<CampaignInterface, 'id'> {}

export class Campaign extends Model<CampaignInterface, CampaignAttributes> implements CampaignInterface {
    public id!: number;
    public parentId!: number;
    public code!: string;
    public title!: string;
    public description!: string;
    public descriptionText!: string;
    public template!: string;
    public type!: string;
    public sendAt!: Date;
    public status!: number;
    public lifeCycleStatus!:number;
    public userId!: number;
    public lastUpdatedBy!: number;
    public accountId!: number;
    public filters?: CampaingnFilters;
    public sortOrder!: number;
    public isRevision!: boolean;
    public revisionId!: number;
    public attachmentId!: number | null;
    public templateStatus!: boolean;
    public isUserAssigned!: boolean;
    public isRecurring!: boolean;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Campaign {
        Campaign.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                code: { type: DataTypes.STRING, allowNull: true, defaultValue: null, unique: "unique-campaign", comment: "campaign code" },
                userId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user identifier" },
                accountId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "account identifier" },
                lastUpdatedBy: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "last updated by user identifier" },
                parentId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "uategory parent identifier" },
                title: { type: DataTypes.STRING, allowNull: false, comment: "campaign title" },
                description: { type: DataTypes.TEXT, allowNull: true, comment: "campaign description" },
                descriptionText: { type: DataTypes.TEXT, allowNull: true, defaultValue: null, comment: "campaign description in text format" },
                template: { type: DataTypes.TEXT, allowNull: true, comment: "campaign template content" },
                attachmentId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "image identifier associated with campaign" },
                type: { type: DataTypes.STRING, allowNull: false, defaultValue: "email", comment: "campaign type" },
                sendAt: { type: DataTypes.DATE, allowNull: true, defaultValue: null, comment: "scheduled send datetime" },
                filters: { type: DataTypes.JSON, allowNull: true, defaultValue: null, comment: "campaign filters (JSON object)" },
                status: { type: DataTypes.INTEGER, allowNull: true, defaultValue: 0, comment: "campaign status" },
                lifeCycleStatus: { type: DataTypes.INTEGER, allowNull: true, defaultValue: 0, comment: "campaign life cycle status" },
                isRevision: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false, comment: "is revision?" },
                revisionId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "revision reference identifier" },
                sortOrder: { type: DataTypes.INTEGER, defaultValue: 0, comment: "campaign sort order" },
                isUserAssigned: { type: DataTypes.BOOLEAN, defaultValue: false, comment: "are users assigned" },
                templateStatus: { type: DataTypes.BOOLEAN, defaultValue: true, comment: "if template is approved" },
                receiverListFileId:{ type: DataTypes.BOOLEAN, defaultValue: true, comment: "If whatsapp campaign to be sent to sent to specified numbers" },
                isRecurring: { type: DataTypes.BOOLEAN, defaultValue: false, comment: "Repeated -> true, false" }
            },
            {
                paranoid: true,
                underscored: true,
                sequelize,
                tableName: 'campaigns',
                timestamps: true,
                indexes: [
                    { name: 'campaign-status-index', fields: ['status'] },
                    { name: 'campaign-type-index', fields: ['type'] },
                    { name: 'campaign-sendat-index', fields: ['send_at'] },
                    { name: 'campaign-code-index', fields: ['code'] },
                ],
            }
        );
        return Campaign;
    }

    public static associate(models: any) {
        Campaign.hasMany(models.CampaignLog, {
  foreignKey: 'campaignId',
  as: 'logs',
});
        Campaign.belongsTo(models.User, { foreignKey: 'userId', as: 'author' });
        Campaign.belongsTo(models.User, { foreignKey: 'lastUpdatedBy', as: 'updatedBy' });
        Campaign.belongsTo(models.Attachment, { foreignKey: 'attachmentId', as: 'campaignAttachment' });
        Campaign.belongsToMany(models.User, { through: models.CampaignUser, foreignKey: 'campaignId', otherKey: 'userId', as: 'users' });
    }
}
