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

export interface SeaQAQuestionAttributes extends Omit<SeaQAQuestionInterface, 'title' | 'description'> {}
export interface SeaQAQuestionCreationAttributes extends Optional<SeaQAQuestionAttributes, 'id' | 'views' | 'answersCount' | 'likesCount' | 'bookmarksCount' | 'status' | 'isGoodQuestion' | 'mergedIntoQuestionId' | 'approvedByAdminId' | 'approvedAt' | 'rejectedReason'> {}

export class SeaQAQuestion extends Model<SeaQAQuestionAttributes, SeaQAQuestionCreationAttributes> implements SeaQAQuestionAttributes {
    public id!: number;
    public accountId!: number | null;
    public userId!: number;
    public code!: string;
    public status!: 'pending' | 'approved' | 'rejected' | 'merged' | 'closed';
    public mergedIntoQuestionId!: number | null;
    public isGoodQuestion!: boolean;
    public approvedByAdminId!: number | null;
    public approvedAt!: Date | null;
    public rejectedReason!: string | null;
    public views!: number;
    public answersCount!: number;
    public likesCount!: number;
    public bookmarksCount!: number;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;
    public readonly deletedAt!: Date | null;

    static initModel(sequelize: Sequelize): typeof SeaQAQuestion {
        SeaQAQuestion.init({
            id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
            accountId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "account identifier" },
            userId: { type: DataTypes.BIGINT, allowNull: false, comment: "author identifier" },
            code: { type: DataTypes.STRING(500), allowNull: false, unique: 'sea_qa_questions_slug_unique', comment: "code for URL", field: 'slug' },
            status: { type: DataTypes.STRING, allowNull: false, defaultValue: 'pending', comment: "pending, approved, rejected, merged, closed" },
            mergedIntoQuestionId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "reference to question it was merged into" },
            isGoodQuestion: { type: DataTypes.BOOLEAN, defaultValue: false, comment: "marked as good by admin" },
            approvedByAdminId: { type: DataTypes.BIGINT, allowNull: true, defaultValue: null, comment: "admin identifier who approved" },
            approvedAt: { type: DataTypes.DATE, allowNull: true, defaultValue: null, comment: "approval timestamp" },
            rejectedReason: { type: DataTypes.TEXT, allowNull: true, defaultValue: null, comment: "reason for rejection" },
            views: { type: DataTypes.INTEGER, defaultValue: 0, comment: "view count" },
            answersCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "cached answer count" },
            likesCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "cached like count" },
            bookmarksCount: { type: DataTypes.INTEGER, defaultValue: 0, comment: "cached bookmark count" }
        }, {
            sequelize,
            tableName: 'sea_qa_questions',
            timestamps: true,
            paranoid: true,
            underscored: true,
            indexes: [
                { name: 'sea_qa_question_status_index', fields: ['status'] },
                { name: 'sea_qa_question_slug_index', fields: ['slug'] },
                { name: 'sea_qa_question_user_index', fields: ['user_id'] }
            ]
        });
        return SeaQAQuestion;
    }

    public static associate(models: any) {
        SeaQAQuestion.belongsTo(models.User, { foreignKey: 'userId', as: 'author' });
        SeaQAQuestion.belongsTo(models.User, { foreignKey: 'approvedByAdminId', as: 'approvedBy' });
        SeaQAQuestion.belongsTo(models.SeaQAQuestion, { foreignKey: 'mergedIntoQuestionId', as: 'mergedInto' });
        SeaQAQuestion.belongsToMany(models.Category, { through: models.SeaQAQuestionCategory, as: 'categories', foreignKey: 'questionId', otherKey: 'categoryId' });
        SeaQAQuestion.hasMany(models.SeaQAAnswer, { foreignKey: 'questionId', as: 'answers' });
        SeaQAQuestion.hasOne(models.SeaQAQuestionContent, { foreignKey: 'questionId', as: 'defaultContent' });
        SeaQAQuestion.hasOne(models.SeaQAQuestionContent, { foreignKey: 'questionId', as: 'content' });
        SeaQAQuestion.hasMany(models.SeaQAQuestionContent, { foreignKey: 'questionId', as: 'questionContents' });
    }
}
