/* eslint-disable @typescript-eslint/lines-between-class-members */
import { CreationOptional, DataTypes, InferAttributes, InferCreationAttributes, Model } from 'sequelize';

import { createIdGenerator } from '../../libs/util';

export const nextSubscriptionItemId = createIdGenerator('si', 14);

// eslint-disable-next-line prettier/prettier
export class SubscriptionItem extends Model<InferAttributes<SubscriptionItem>, InferCreationAttributes<SubscriptionItem>> {
  declare id: CreationOptional<string>;
  declare livemode: boolean;

  // The identifier of the subscription this item belongs to.
  declare subscription_id: string;

  // The price the customer is subscribed to.
  declare price_id: string;

  declare quantity: number;

  declare metadata: Record<string, any>;

  declare billing_thresholds?: {
    usage_gte: number;
  };

  // TODO: following fields not supported
  // tax_rates

  declare created_at: CreationOptional<Date>;
  declare updated_at: CreationOptional<Date>;

  public static readonly GENESIS_ATTRIBUTES = {
    id: {
      type: DataTypes.STRING(18),
      primaryKey: true,
      allowNull: false,
      defaultValue: nextSubscriptionItemId,
    },
    livemode: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
    },
    subscription_id: {
      type: DataTypes.STRING(30),
      allowNull: false,
    },
    price_id: {
      type: DataTypes.STRING(30),
      allowNull: false,
    },
    quantity: {
      type: DataTypes.INTEGER,
      allowNull: true,
    },
    metadata: {
      type: DataTypes.JSON,
      allowNull: true,
    },
    billing_threshold: {
      type: DataTypes.JSON,
      allowNull: true,
    },
    created_at: {
      type: DataTypes.DATE,
      defaultValue: DataTypes.NOW,
      allowNull: false,
    },
    updated_at: {
      type: DataTypes.DATE,
      defaultValue: DataTypes.NOW,
      allowNull: false,
    },
  };

  public static initialize(sequelize: any) {
    this.init(SubscriptionItem.GENESIS_ATTRIBUTES, {
      sequelize,
      modelName: 'SubscriptionItem',
      tableName: 'subscription_items',
      createdAt: 'created_at',
      updatedAt: 'updated_at',
    });
  }

  public static associate(models: any) {
    this.belongsTo(models.Subscription, {
      foreignKey: 'subscription_id',
      as: 'subscription',
    });
    this.hasOne(models.Price, {
      sourceKey: 'price_id',
      foreignKey: 'id',
      as: 'price',
    });
  }

  public static async isPriceUsed(priceId: string) {
    const count = await SubscriptionItem.count({
      where: { price_id: priceId },
    });

    return count > 0;
  }
}

export type TSubscriptionItem = InferAttributes<SubscriptionItem>;
