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

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

const nextId = createCodeGenerator('', 8);

// @link https://stripe.com/docs/api/discounts
// eslint-disable-next-line prettier/prettier
export class Discount extends Model<InferAttributes<Discount>, InferCreationAttributes<Discount>> {
  declare id: CreationOptional<string>;
  declare livemode: boolean;

  declare coupon_id: string;
  declare promotion_code_id?: string;
  declare customer_id: string;
  declare subscription_id?: string;
  declare checkout_session_id?: string;
  declare invoice_id?: string;
  declare invoice_item_id?: string;
  declare confirmed?: boolean;

  declare start: number;
  declare end: number | null;

  declare verification_method?: string;
  declare verification_data?: Record<string, any>;
  declare metadata?: Record<string, any>;

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

  public static readonly GENESIS_ATTRIBUTES = {
    id: {
      type: DataTypes.STRING(15),
      primaryKey: true,
      allowNull: false,
      defaultValue: nextId,
    },
    livemode: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
    },
    coupon_id: {
      type: DataTypes.STRING(30),
      allowNull: false,
    },
    customer_id: {
      type: DataTypes.STRING(30),
      allowNull: false,
    },
    promotion_code_id: {
      type: DataTypes.STRING(30),
      allowNull: true,
    },
    subscription_id: {
      type: DataTypes.STRING(30),
      allowNull: true,
    },
    checkout_session_id: {
      type: DataTypes.STRING(30),
      allowNull: true,
    },
    invoice_id: {
      type: DataTypes.STRING(30),
      allowNull: true,
    },
    invoice_item_id: {
      type: DataTypes.STRING(30),
      allowNull: true,
    },
    start: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
    end: {
      type: DataTypes.INTEGER,
      allowNull: true,
    },
    verification_method: {
      type: DataTypes.STRING(50),
      allowNull: true,
    },
    verification_data: {
      type: DataTypes.JSON,
      allowNull: true,
    },
    metadata: {
      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(
      {
        ...Discount.GENESIS_ATTRIBUTES,
        confirmed: {
          type: DataTypes.BOOLEAN,
          defaultValue: true,
          allowNull: false,
        },
      },
      {
        sequelize,
        modelName: 'Discount',
        tableName: 'discounts',
        createdAt: 'created_at',
        updatedAt: 'updated_at',
      }
    );
  }

  public static associate(models: any) {
    this.belongsTo(models.Customer, {
      foreignKey: 'customer_id',
      as: 'customer',
    });
    this.belongsTo(models.Coupon, {
      foreignKey: 'coupon_id',
      as: 'coupon',
    });
    this.belongsTo(models.PromotionCode, {
      foreignKey: 'promotion_code_id',
      as: 'promotionCode',
    });
  }
}

export type TDiscount = InferAttributes<Discount>;
