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

export interface SubscriptionAttributes extends Optional<SubscriptionInterface, 'id'> { }

export class Subscription extends Model<SubscriptionInterface, SubscriptionAttributes> implements SubscriptionInterface {
    public id!: number;
    public planId!: number;
    public priceId!: number;
    public userId!: number;
    public accountId!: number;
    public externalSubscriptionId!: string;
    public currentPeriodStart!: Date;
    public currentPeriodEnd!: Date;
    public gateway!: string;
    public status!: number;
    public planData!: object | null;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Subscription {
        Subscription.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "Unique numeric identifier for the subscription record" },
                planId: { type: DataTypes.BIGINT, allowNull: true, comment: "ID of the plan opted for subscription" },
                priceId: { type: DataTypes.BIGINT, allowNull: true, comment: "ID of the price opted for plan subscription" },
                userId: { type: DataTypes.BIGINT, allowNull: false, comment: "ID of the user who owns this subscription" },
                accountId: { type: DataTypes.BIGINT, allowNull: true, comment: "ID of the user who owns this subscription" },
                externalSubscriptionId: { type: DataTypes.STRING, allowNull: true, unique: "unique-subscription", comment: "Identifier of the subscription in the payment gateway" },
                gateway: { type: DataTypes.STRING, allowNull: false, defaultValue: process.env.PAYMENT_GATEWAY, comment: "Payment gateway type (e.g., razorpay)" },
                currentPeriodStart: { type: DataTypes.DATE, allowNull: true, defaultValue: null, comment: "Start date/time of the current billing period" },
                currentPeriodEnd: { type: DataTypes.DATE, allowNull: true, defaultValue: null, comment: "End date/time of the current billing period" },
                status: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 0, comment: "Subscription status (0 = inactive, 1 = active, 2 = canceled, etc.)" },
                planData: { type: DataTypes.JSON, allowNull: true, comment: "planObject" },
            },
            {
                paranoid: true,
                underscored: true,
                sequelize,
                tableName: 'subscriptions',
                timestamps: true,
                indexes: [
                    { name: 'subscription_index_status', fields: ['status'] },
                    { name: 'subscription_index_created_at', fields: ['created_at'] }
                    // { name: 'subscription_index_currency_status_created', fields: [sequelize.literal("JSON_UNQUOTE(JSON_EXTRACT(plan_data, '$.currency'))"), 'status', 'created_at'] },
                    // { name: 'subscription_index_plan_currency_fn', fields: [sequelize.literal("JSON_UNQUOTE(JSON_EXTRACT(plan_data, '$.currency'))")] },
                    // { name: 'subscription_index_plan_amount_fn', fields: [sequelize.literal("JSON_EXTRACT(plan_data, '$.amount')")] }
                ]
            }
        );
        return Subscription;
    }

    public static associate(models: any) {
        Subscription.belongsTo(models.User, { foreignKey: 'userId', as: 'user' });
        Subscription.hasMany(models.Transaction, { foreignKey: 'subscriptionId', as: 'transactions', onDelete: 'cascade', hooks: true });
        Subscription.hasOne(models.Transaction, { foreignKey: 'subscriptionId', as: 'transaction' });
    }
}
