import { DataTypes, Model, Optional, Sequelize } from 'sequelize';
import * as Constants from "../config/constants"

export interface RoleAttributes extends Optional<RoleInterface, 'id'> { }

export class Role extends Model<RoleInterface, RoleAttributes> implements RoleInterface {
    public id!: number;
    public accountId!: number | null;
    public userId!: number | null;
    public lastUpdatedBy!: number;
    public code!: string;
    public isRevision!: boolean;
    public revisionId!: number | null;
    public isDefault!: boolean;
    public status!: number;
    public sortOrder!: number;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Role {
        Role.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                accountId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, unique: "unique-role", comment: "account identifier" },
                code: { type: DataTypes.STRING, allowNull: false, unique: "unique-role", comment: "role-code" },
                userId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user identifier" },
                lastUpdatedBy: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user identifier" },
                isRevision: { type: DataTypes.BOOLEAN, allowNull: true, defaultValue: false, comment: "isRevision" },
                revisionId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "revision ref identifier" },
                isDefault: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false, comment: "isDefault" },
                status: { type: DataTypes.INTEGER, allowNull: true, defaultValue: Constants.ROLE.STATUS.ACTIVE, comment: "Status of record" },
                sortOrder: { type: DataTypes.INTEGER, defaultValue: 0, comment: "role sort order" },
            },
            {
                paranoid: true,
                underscored: true,
                sequelize,
                tableName: 'roles',
                timestamps: true,
            }
        );
        return Role;
    }

    public static associate(models: any) {
        Role.belongsTo(models.User, { foreignKey: 'userId', as: 'author' });
        Role.belongsTo(models.User, { foreignKey: 'lastUpdatedBy', as: 'updatedBy' }),
        Role.hasOne(models.RoleContent, { foreignKey: 'roleId', as: 'defaultContent', onDelete: 'cascade', hooks: true }),
        Role.hasOne(models.RoleContent, { foreignKey: 'roleId', as: 'content', onDelete: 'cascade', hooks: true }),
        Role.hasOne(models.RoleContent, { foreignKey: 'roleId', as: 'roleContent', onDelete: 'cascade', hooks: true });
        Role.hasMany(models.RoleContent, { foreignKey: 'roleId', as: 'roleContents', onDelete: 'cascade', hooks: true });
        Role.belongsToMany(models.Permission, { through: "role_permissions", foreignKey: "roleId", as: "rolePermissions", otherKey: "permissionId" });
    }
}
