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

export interface UserAttributes extends Optional<UserInterface, 'id'> { }

export class User extends Model<UserInterface, UserAttributes> implements UserInterface {
    public id!: number;
    public accountId!: number;
    public username!: string;
    public email!: string;
    public password!: string;
    public countryCode!: string;
    public mobile!: string;
    public status!: number;
    public onlineStatus!: number;
    public google!: string;
    public apple!: string;
    public facebook!: string;
    public sameOnWhatsapp!: boolean;
    public readonly createdAt!: Date;
    public readonly updatedAt!: Date;

    static initModel(sequelize: Sequelize): typeof User {
        User.init(
            {
                id: { type: DataTypes.BIGINT, autoIncrement: true, primaryKey: true, comment: "unique identifier" },
                accountId: { type: DataTypes.BIGINT, allowNull: false, comment: "account identifier" },
                username: { type: DataTypes.STRING, allowNull: true, defaultValue: null, unique: "unique-username", comment: "User's Username" },
                email: { type: DataTypes.STRING, allowNull: true, defaultValue: null, unique: "unique-email", comment: "User's Email id" },
                password: { type: DataTypes.STRING, allowNull: true, defaultValue: null, comment: "User's password" },
                countryCode: { type: DataTypes.STRING, allowNull: true, defaultValue: null, unique: "unique-mobile", comment: "User's country code" },
                mobile: { type: DataTypes.STRING, allowNull: true, defaultValue: null, unique: "unique-mobile", comment: "User's mobile no" },
                status: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 0, comment: "User's Account status" },
                onlineStatus: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 0, comment: "User's online status" },
                google: { type: DataTypes.STRING, allowNull: true, defaultValue: null, comment: "Google login provider" },
                apple: { type: DataTypes.STRING, allowNull: true, defaultValue: null, comment: "Apple login provider" },
                facebook: { type: DataTypes.STRING, allowNull: true, defaultValue: null, comment: "Facebook login provider" },
                sameOnWhatsapp: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true, comment: "same number on whatsapp" }
            },
            {
                paranoid: true,
                underscored: true,
                sequelize,
                tableName: 'users',
                timestamps: true,
                indexes: [
                    { name: 'user-search-index', fields: ['email', 'mobile', 'username'], type: 'FULLTEXT' }
                ]
            }
        );
        return User;
    }

    public static associate(models: any) {
        User.hasOne(models.UserProfile, { foreignKey: 'userId', as: 'userProfile', onDelete: 'cascade', hooks: true });
        User.hasMany(models.UserProfile, { foreignKey: 'userId', as: 'userProfiles', onDelete: 'cascade', hooks: true });
        User.hasOne(models.UserAccount, { foreignKey: "userId", as: "userAccount", onDelete: "cascade", hooks: true });
        User.hasMany(models.UserAccount, { foreignKey: "userId", as: "userAccounts", onDelete: "cascade", hooks: true });
        User.hasOne(models.UserRole, { foreignKey: "userId", as: "userRole" });
        User.belongsToMany(models.Role, { through: models.UserRole, foreignKey: "userId", otherKey: "roleId", as: "userRoles", onDelete: "cascade", hooks: true });
        User.hasOne(models.UserSetting, { foreignKey: 'userId', as: 'userSetting', onDelete: 'cascade', hooks: true });
        User.hasOne(models.UserDevice, { foreignKey: 'userId', as: 'userDevice', onDelete: 'cascade', hooks: true });
        User.hasMany(models.UserDevice, { foreignKey: 'userId', as: 'userDevices', onDelete: 'cascade', hooks: true });
        User.hasOne(models.Token, { foreignKey: 'userId', as: 'userToken', onDelete: 'cascade', hooks: true });
        User.hasMany(models.Token, { foreignKey: 'userId', as: 'userTokens', onDelete: 'cascade', hooks: true });
        User.belongsToMany(models.Campaign, { through: models.CampaignUser, foreignKey: 'userId', otherKey: 'campaignId', as: 'campaigns' });
        User.hasMany(models.Subscription, { foreignKey: 'userId', as: 'userSubscriptions', onDelete: 'cascade', hooks: true });
        User.hasOne(models.Subscription, { foreignKey: 'userId', as: 'userSubscription' });
        User.hasMany(models.UserFollower, { foreignKey: 'followerId', as: 'following', onDelete: 'cascade', hooks: true });
        User.hasMany(models.UserFollower, { foreignKey: 'followingId', as: 'followers', onDelete: 'cascade', hooks: true });
    }
}
