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

export interface PostAttributes extends Optional<PostInterface, 'id'> { }

export class Post extends Model<PostInterface, PostAttributes> implements PostInterface {
    public id!: number;
    public code!: string;
    public postType!: string;
    public status!: string;
    public visibility!: string;
    public isExclusive!: boolean;
    public publishedAt?: Date | null;
    public isFeatured!: boolean;
    public sortOrder!: number;
    public isRevision!: boolean;
    public revisionId!: number;
    public authorId!: number;
    public accountId!: number;
    public lastUpdatedBy!: number;
    public postAuthorId!: number | null;
    public wpPostId!: number | null;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof Post {
        Post.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                authorId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "author identifier" },
                accountId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user account identifier" },
                lastUpdatedBy: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "user identifier" },
                code: { type: DataTypes.STRING, allowNull: false, unique: "unique-post", comment: "post code" },
                postType: { type: DataTypes.STRING, allowNull: false, unique: "unique-post", comment: "post type" },
                isRevision: { type: DataTypes.BOOLEAN, allowNull: true, defaultValue: false, comment: "is revision?" },
                revisionId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "revision ref identifier" },
                sortOrder: { type: DataTypes.INTEGER, defaultValue: 0, comment: "post sort order" },
                isFeatured: { type: DataTypes.BOOLEAN, defaultValue: false, comment: "if content is premium" },
                isExclusive: { type: DataTypes.BOOLEAN, defaultValue: false, comment: "if content is exclusive for subscribers" },
                status: { type: DataTypes.STRING, allowNull: true, defaultValue: 'draft', comment: "post status draft/publish/private" },
                visibility: { type: DataTypes.STRING, allowNull: true, defaultValue: 'logged_in', comment: "post visibility public/logged_in/subscribers_only" },
                publishedAt: { type: DataTypes.DATE, allowNull: true, defaultValue: null, comment: "publish date" },
                wpPostId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "original wordpress post identifier" },
            },
            {
                paranoid: true,
                underscored: true,
                sequelize,
                tableName: 'post',
                timestamps: true,
                indexes: [
                    { name: 'post-revision-index', fields: ['is_revision'] },
                    { name: 'post-index', fields: ['status'] },
                    { name: 'post-code-index', fields: ['code'] },
                    { name: 'post-type-index', fields: ['post_type'] }
                ]

            }
        );
        return Post;
    }

    public static associate(models: any) {
        Post.hasOne(models.PostContent, { foreignKey: 'postId', as: 'defaultContent' });
        Post.hasOne(models.PostContent, { foreignKey: 'postId', as: 'content' });
        Post.hasOne(models.PostContent, { foreignKey: 'postId', as: 'postContent' });
        Post.hasMany(models.PostContent, { foreignKey: 'postId', as: 'postContents' });
        Post.belongsTo(models.User, { foreignKey: 'authorId', as: 'author' });
        Post.belongsTo(models.User, { foreignKey: 'lastUpdatedBy', as: 'updatedBy' });
        Post.belongsToMany(models.Category, { through: models.PostCategory, foreignKey: 'postId', otherKey: 'categoryId', as: 'postCategories' });
        Post.belongsToMany(models.Attachment, { through: models.PostAttachment, foreignKey: "postId", as: "postAttachments", otherKey: "attachmentId" });
        Post.belongsToMany(models.Attachment, { through: { model: models.PostAttachment, scope: { isFeatured: true } }, foreignKey: "postId", otherKey: "attachmentId", as: "featuredImage" });
        Post.belongsToMany(models.Category, { through: models.PostTag, foreignKey: "postId", otherKey: "categoryId", as: "postTags" });
    }
}
