import * as Sequelize from 'sequelize';
import { Op } from 'sequelize';
import { DataTypes, Model, Optional } from 'sequelize';
import type { Apartment, ApartmentId } from './Apartment';
import type { Bed, BedId } from './Bed';
import type { Incident, IncidentId } from './Incident';
import type { User, UserId } from './User';
export interface RoomAttributes {
	id: string;
	apartment_id: string;
	name: string;
	code: string;
	floor?: number | null;
	status: 'active' | 'inactive';
	deleted_at?: Date | null;
	deleted_by?: string | null;
	created_by?: string | null;
	updated_by?: string | null;
	created_at: Date;
	updated_at: Date;
}
export type RoomPk = 'id';
export type RoomId = Room[RoomPk];
export type RoomOptionalAttributes =
	| 'id'
	| 'floor'
	| 'status'
	| 'deleted_at'
	| 'deleted_by'
	| 'created_by'
	| 'updated_by'
	| 'created_at'
	| 'updated_at';
export type RoomCreationAttributes = Optional<RoomAttributes, RoomOptionalAttributes>;
export class Room extends Model<RoomAttributes> implements RoomAttributes {
	declare id: string;
	declare apartment_id: string;
	declare name: string;
	declare code: string;
	declare floor?: number | null;
	declare status: 'active' | 'inactive';
	declare deleted_at?: Date | null;
	declare deleted_by?: string | null;
	declare created_by?: string | null;
	declare updated_by?: string | null;
	declare created_at: Date;
	declare updated_at: Date;
	// Room belongsTo Apartment via apartment_id
	declare apartment: Apartment;
	declare getApartment: Sequelize.BelongsToGetAssociationMixin<Apartment>;
	declare setApartment: Sequelize.BelongsToSetAssociationMixin<Apartment, ApartmentId>;
	declare createApartment: Sequelize.BelongsToCreateAssociationMixin<Apartment>;
	// Room hasMany Bed via room_id
	declare beds: Bed[];
	declare getBeds: Sequelize.HasManyGetAssociationsMixin<Bed>;
	declare setBeds: Sequelize.HasManySetAssociationsMixin<Bed, BedId>;
	declare addBed: Sequelize.HasManyAddAssociationMixin<Bed, BedId>;
	declare addBeds: Sequelize.HasManyAddAssociationsMixin<Bed, BedId>;
	declare createBed: Sequelize.HasManyCreateAssociationMixin<Bed>;
	declare removeBed: Sequelize.HasManyRemoveAssociationMixin<Bed, BedId>;
	declare removeBeds: Sequelize.HasManyRemoveAssociationsMixin<Bed, BedId>;
	declare hasBed: Sequelize.HasManyHasAssociationMixin<Bed, BedId>;
	declare hasBeds: Sequelize.HasManyHasAssociationsMixin<Bed, BedId>;
	declare countBeds: Sequelize.HasManyCountAssociationsMixin;
	// Room hasMany Incident via room_id
	declare incidents: Incident[];
	declare getIncidents: Sequelize.HasManyGetAssociationsMixin<Incident>;
	declare setIncidents: Sequelize.HasManySetAssociationsMixin<Incident, IncidentId>;
	declare addIncident: Sequelize.HasManyAddAssociationMixin<Incident, IncidentId>;
	declare addIncidents: Sequelize.HasManyAddAssociationsMixin<Incident, IncidentId>;
	declare createIncident: Sequelize.HasManyCreateAssociationMixin<Incident>;
	declare removeIncident: Sequelize.HasManyRemoveAssociationMixin<Incident, IncidentId>;
	declare removeIncidents: Sequelize.HasManyRemoveAssociationsMixin<Incident, IncidentId>;
	declare hasIncident: Sequelize.HasManyHasAssociationMixin<Incident, IncidentId>;
	declare hasIncidents: Sequelize.HasManyHasAssociationsMixin<Incident, IncidentId>;
	declare countIncidents: Sequelize.HasManyCountAssociationsMixin;
	// Room belongsTo User via created_by
	declare created_by_user: User;
	declare getCreated_by_user: Sequelize.BelongsToGetAssociationMixin<User>;
	declare setCreated_by_user: Sequelize.BelongsToSetAssociationMixin<User, UserId>;
	declare createCreated_by_user: Sequelize.BelongsToCreateAssociationMixin<User>;
	// Room belongsTo User via deleted_by
	declare deleted_by_user: User;
	declare getDeleted_by_user: Sequelize.BelongsToGetAssociationMixin<User>;
	declare setDeleted_by_user: Sequelize.BelongsToSetAssociationMixin<User, UserId>;
	declare createDeleted_by_user: Sequelize.BelongsToCreateAssociationMixin<User>;
	// Room belongsTo User via updated_by
	declare updated_by_user: User;
	declare getUpdated_by_user: Sequelize.BelongsToGetAssociationMixin<User>;
	declare setUpdated_by_user: Sequelize.BelongsToSetAssociationMixin<User, UserId>;
	declare createUpdated_by_user: Sequelize.BelongsToCreateAssociationMixin<User>;
	static initModel(sequelize: Sequelize.Sequelize): typeof Room {
		return Room.init(
			{
				id: {
					type: DataTypes.UUID,
					allowNull: false,
					defaultValue: DataTypes.UUIDV4,
					primaryKey: true,
				},
				apartment_id: {
					type: DataTypes.UUID,
					allowNull: false,
					references: {
						model: 'apartments',
						key: 'id',
					},
				},
				name: {
					type: DataTypes.STRING(200),
					allowNull: false,
				},
				code: {
					type: DataTypes.STRING(50),
					allowNull: false,
				},
				floor: {
					type: DataTypes.INTEGER,
					allowNull: true,
				},
				status: {
					type: DataTypes.ENUM('active', 'inactive'),
					allowNull: false,
					defaultValue: 'active',
				},
				deleted_at: {
					type: DataTypes.DATE,
					allowNull: true,
				},
				deleted_by: {
					type: DataTypes.UUID,
					allowNull: true,
					references: {
						model: 'users',
						key: 'id',
					},
				},
				created_by: {
					type: DataTypes.UUID,
					allowNull: true,
					references: {
						model: 'users',
						key: 'id',
					},
				},
				updated_by: {
					type: DataTypes.UUID,
					allowNull: true,
					references: {
						model: 'users',
						key: 'id',
					},
				},
				created_at: {
					type: DataTypes.DATE,
					allowNull: false,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
				updated_at: {
					type: DataTypes.DATE,
					allowNull: false,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
			},
			{
				sequelize,
				tableName: 'rooms',
				schema: 'public',
				hasTrigger: true,
				timestamps: false,

				scopes: {
					default: {
						where: {
							deleted_at: null,
						},
					},
					withDeleted: {},
					onlyDeleted: {
						where: {
							deleted_at: { [Op.ne]: null },
						},
					},
				},
				indexes: [
					{
						name: 'idx_rooms_apartment_id',
						fields: [{ name: 'apartment_id' }],
					},
					{
						name: 'idx_rooms_code',
						fields: [{ name: 'code' }],
					},
					{
						name: 'idx_rooms_deleted_at',
						fields: [{ name: 'deleted_at' }],
					},
					{
						name: 'idx_rooms_status',
						fields: [{ name: 'status' }],
					},
					{
						name: 'rooms_pkey',
						unique: true,
						fields: [{ name: 'id' }],
					},
					{
						name: 'uq_rooms_code',
						unique: true,
						fields: [{ name: 'apartment_id' }, { name: 'code' }],
					},
				],
			},
		);
	}
}
