import {
	Association,
	CreationAttributes,
	CreationOptional,
	DataTypes,
	HasManyGetAssociationsMixin,
	HasOneCreateAssociationMixin,
	HasOneGetAssociationMixin,
	InferAttributes,
	InferCreationAttributes,
	Model,
	NonAttribute,
} from "@sequelize/core";
import { Post } from "./Post";
import { UserPerms } from "./UserPerms";
import { Auth } from "./Auth";
import {
	PrimaryKey,
	Attribute,
	AutoIncrement,
	Unique,
	UpdatedAt,
	CreatedAt,
} from "@sequelize/core/decorators-legacy";

type UserCreationAttributes = {
	username: string;
	password: string;
	perms?: Partial<InferAttributes<UserPerms>>;
};
export class User extends Model<
	InferAttributes<User>,
	InferCreationAttributes<User>
> {
	@Attribute(DataTypes.INTEGER)
	@PrimaryKey
	@AutoIncrement
	@Unique
	declare id: CreationOptional<number>;
	@Attribute(DataTypes.STRING)
	@Unique()
	declare username: string;
	@Attribute(DataTypes.STRING)
	declare password: string;

	/** @description The time and date when the object was created */
	@CreatedAt declare createdAt: CreationOptional<Date>;
	/** @description The time and date when the object was last modified */
	@UpdatedAt declare updatedAt: CreationOptional<Date>;

	// Associations
	declare getAuthTokens: HasManyGetAssociationsMixin<Auth>;
	declare getPosts: HasManyGetAssociationsMixin<Post>;
	declare getPerms: HasOneGetAssociationMixin<UserPerms>;
	declare createPerms: HasOneCreateAssociationMixin<UserPerms>;

	/** Defined by {@link Auth.user} */
	declare authtokens?: NonAttribute<Auth[]>;
	/** Defined by {@link UserPerms.user} */
	declare perms?: CreationOptional<CreationAttributes<UserPerms>>;
	/** Defined by {@link Post.user} */
	declare posts?: CreationOptional<Post[]>;

	declare static associations: {
		perms: Association<UserPerms, User>;
		posts: Association<Post, User>;
		authtokens: Association<Auth, User>;
	};
}
export function addUserScopes() {
	User.addScope("defaultScope", {
		attributes: {
			exclude: ["password", "createdAt", "updatedAt"],
		},
	});
	User.addScope("withPerms", {
		include: [{ association: "perms" }],
	});
	User.addScope("withAuthtokens", {
		include: [{ association: "authtokens" }],
	});
}
