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

export interface PlanAttributes extends Optional<PlanInterface, 'id'> { }

export class Plan extends Model<PlanInterface, PlanAttributes> implements PlanInterface {
    public id!: number;
    public code!: string;
    public type!: number;
    public gateway!: string;
    public trialPeriod!: number;
    public userId!: number;
    public lastUpdatedBy!: number;
    public accountId!: number;
    public status!: number;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Plan {
        Plan.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                code: { type: DataTypes.STRING, allowNull: false, unique: "unique-plan", comment: "plan code" },
                type: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 2, comment: "1->free,2->one-time3->subscription" },
                gateway: { type: DataTypes.STRING, allowNull: false, defaultValue: process.env.PAYMENT_GATEWAY, comment: "Type of gateway used eg: stripe, razorpay, etc." },
                trialPeriod: { type: DataTypes.INTEGER, allowNull: true, defaultValue: 0, comment: "trial period for the subscription"},
                userId: { type: DataTypes.BIGINT, allowNull: false, comment: "author of the record" },
                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" },
                status: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 0, comment: "User's Account status" },
                sortOrder: { type: DataTypes.INTEGER, defaultValue: 0, comment: "category type sort order" },
            },
            { 
                paranoid: true, 
                underscored: true, 
                sequelize, 
                tableName: 'plans', 
                timestamps: true,
                indexes: [
                ]
            }
        );
        return Plan;
    }

    public static associate(models: any) {
        Plan.hasOne(models.PlanContent, { foreignKey: 'planId', as: 'defaultContent' });
        Plan.hasOne(models.PlanContent, { foreignKey: 'planId', as: 'content' });
        Plan.hasOne(models.PlanContent, { foreignKey: 'planId', as: 'planContent' });
        Plan.hasMany(models.PlanContent, { foreignKey: 'planId', as: 'planContents', onDelete: 'cascade', onUpdate: 'cascade' });
        Plan.hasOne(models.Price, { foreignKey: 'planId', as: 'price' });
        Plan.hasMany(models.Price, { foreignKey: 'planId', as: 'prices', onDelete: 'cascade', onUpdate: 'cascade' });
        Plan.belongsTo(models.User, { foreignKey: 'userId', as: 'author' });
        Plan.belongsTo(models.User, { foreignKey: 'lastUpdatedBy', as: 'updatedBy' });
    }
}
