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

export interface CategoryAttributes extends Optional<CategoryInterface, 'id'> { }

export class Category extends Model<CategoryInterface, CategoryAttributes> implements CategoryInterface {
    public id!: number;
    public code!: string;
    public categoryTypeId!: number;
    public parentId!: number;
    public isRevision!: boolean;
    public revisionId!: number;
    public userId!: number;
    public imageId!: number;
    public adminOnly!: boolean;
    public accountId!: number | null;
    public lastUpdatedBy!: number;
    public status!: number;
    public orderSequence!: Text;
    public level!: number;
    public sortOrder!: number;
    public refLink!: Text | null;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Category {
        Category.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                userId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "User identifier" },
                accountId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, unique: "unique-category", comment: "account identifier" },
                adminOnly: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false, comment: "if category can be managed by system admin only? 0=>Account admin can manage it for subaccount, 1=> Its exclusive for system admin only" },
                categoryTypeId: { type: DataTypes.BIGINT, allowNull: false, comment: "category type identifier" },
                parentId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "uategory parent identifier" },
                lastUpdatedBy: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user identifier" },
                code: { type: DataTypes.STRING, allowNull: true, defaultValue: null, unique: "unique-category", comment: "category code" },
                imageId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "identity of image associated with category" },
                isRevision: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false, comment: "is revision?" },
                revisionId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "revision ref identifier" },
                orderSequence: { type: DataTypes.TEXT, defaultValue: null, comment: "order sequence for tree structure" },
                level: { type: DataTypes.INTEGER, defaultValue: null, comment: "level of category" },
                sortOrder: { type: DataTypes.INTEGER, defaultValue: 0, comment: "category sort order" },
                status: { type: DataTypes.INTEGER, defaultValue: 1, comment: "status of category. 0-> Inactive, 1-> Active" },
                refLink: { type: DataTypes.TEXT, allowNull: true, defaultValue: null, comment: "ref link" }
            },
            {
                paranoid: true,
                underscored: true,
                sequelize,
                tableName: 'categories',
                timestamps: true,
                indexes: [
                    { name: 'category-revision-index', fields: ['is_revision'] },
                    { name: 'category-status-index', fields: ['status'] },
                    { name: 'category-code-index', fields: ['code'] },
                    { name: 'category-sort-order-index', fields: ['sort_order'] }
                ]
            }
        );
        return Category;
    }

    public static associate(models: any) {
        Category.belongsTo(models.CategoryType, { foreignKey: 'categoryTypeId', as: 'categoryType' });
        Category.belongsTo(models.User, { foreignKey: 'userId', as: 'author' });
        Category.belongsTo(models.User, { foreignKey: 'lastUpdatedBy', as: 'updatedBy' });
        Category.belongsTo(models.Category, { foreignKey: 'parentId', as: 'parentCategory', onDelete: 'cascade', hooks: true });
        Category.hasMany(models.Category, { foreignKey: 'parentId', as: 'subCategories', onDelete: 'cascade', hooks: true });
        Category.belongsTo(models.Attachment, { foreignKey: 'imageId', as: 'categoryImage' });
        Category.hasOne(models.CategoryContent, { foreignKey: 'categoryId', as: 'defaultContent', onDelete: 'cascade', hooks: true });
        Category.hasOne(models.CategoryContent, { foreignKey: 'categoryId', as: 'content', onDelete: 'cascade', hooks: true });
        Category.hasMany(models.CategoryContent, { foreignKey: 'categoryId', as: 'categoryContents', onDelete: 'cascade', hooks: true });
    }
}
