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

export interface PromotionAttributes extends Optional<PromotionInterface, 'id'> { }

export class Promotion extends Model<PromotionInterface, PromotionAttributes> implements PromotionInterface {
    public id!: number;
    public code!: string;
    public userId!: number;
    public imageId!: number;
    public lastUpdatedBy!: number;
    public accountId!: number;
    public link!: string;
    public type!: string;
    public publishAt!: Date;
    public expireAt!: Date;
    public isPremium!: boolean;
    public status!: number;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Promotion {
        Promotion.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                code: { type: DataTypes.STRING, allowNull: false, unique: "unique-promotion", comment: "promotion code" },
                userId: { type: DataTypes.BIGINT, allowNull: false, comment: "author of the record" },
                imageId: { type: DataTypes.BIGINT, allowNull: true,  defaultValue: null, comment: "image ID" },
                lastUpdatedBy: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user identifier" },
                accountId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "author account of the record" },
                isRevision: { type: DataTypes.BOOLEAN, allowNull: true, defaultValue: false, comment: "is revision?" },
                revisionId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "revision ref identifier" },
                link: { type: DataTypes.STRING,allowNull: true,defaultValue: null,comment: "external or internal link for the announcement" },
                type: { type: DataTypes.STRING,allowNull: false,comment: "type of announcement (e.g. Banner, Announcement)" },
                publishAt: { type: DataTypes.DATE,allowNull: false,comment: "publish datetime" },
                expireAt: { type: DataTypes.DATE,allowNull: true,defaultValue: null,comment: "expiry datetime (null = never expires)" },
                isPremium: { type: DataTypes.BOOLEAN,allowNull: false,defaultValue: false,comment: "whether the announcement is for premium users",},
                status: { type: DataTypes.INTEGER, allowNull: true, defaultValue: 1, comment: "promotion status" },
                sortOrder: { type: DataTypes.INTEGER, defaultValue: 0, comment: "promotion sort order" },
            },
            { 
                paranoid: true, 
                underscored: true, 
                sequelize, 
                tableName: 'promotions', 
                timestamps: true,
                indexes: []
            }
        );
        return Promotion;
    }

    public static associate(models: any) {
        Promotion.hasOne(models.PromotionContent, { foreignKey: 'promotionId', as: 'defaultContent' });
        Promotion.hasOne(models.PromotionContent, { foreignKey: 'promotionId', as: 'content' });
        Promotion.hasOne(models.PromotionContent, { foreignKey: 'promotionId', as: 'promotionContent' });
        Promotion.hasMany(models.PromotionContent, { foreignKey: 'promotionId', as: 'promotionContents', onDelete: 'cascade', onUpdate: 'cascade' });
        Promotion.belongsTo(models.Attachment, { foreignKey: 'imageId', as: 'promotionImage' });
        Promotion.belongsTo(models.User, { foreignKey: 'userId', as: 'author' });
        Promotion.belongsTo(models.User, { foreignKey: 'lastUpdatedBy', as: 'updatedBy' });
    }
}
