import type { Sequelize } from 'sequelize';
import { AuditDeadLetter as _AuditDeadLetter } from './AuditDeadLetter';
import type { AuditDeadLetterAttributes, AuditDeadLetterCreationAttributes } from './AuditDeadLetter';
import { AuditOutbox as _AuditOutbox } from './AuditOutbox';
import type { AuditOutboxAttributes, AuditOutboxCreationAttributes } from './AuditOutbox';
import { AuthAuditLog as _AuthAuditLog } from './AuthAuditLog';
import type { AuthAuditLogAttributes, AuthAuditLogCreationAttributes } from './AuthAuditLog';
import { AuthAuditLogsDefault as _AuthAuditLogsDefault } from './AuthAuditLogsDefault';
import type { AuthAuditLogsDefaultAttributes, AuthAuditLogsDefaultCreationAttributes } from './AuthAuditLogsDefault';
import { Client as _Client } from './Client';
import type { ClientAttributes, ClientCreationAttributes } from './Client';
import { EmailVerifyToken as _EmailVerifyToken } from './EmailVerifyToken';
import type { EmailVerifyTokenAttributes, EmailVerifyTokenCreationAttributes } from './EmailVerifyToken';
import { EntityChangeLog as _EntityChangeLog } from './EntityChangeLog';
import type { EntityChangeLogAttributes, EntityChangeLogCreationAttributes } from './EntityChangeLog';
import { EntityChangeLogsDefault as _EntityChangeLogsDefault } from './EntityChangeLogsDefault';
import type {
	EntityChangeLogsDefaultAttributes,
	EntityChangeLogsDefaultCreationAttributes,
} from './EntityChangeLogsDefault';
import { File as _File } from './File';
import type { FileAttributes, FileCreationAttributes } from './File';
import { FileVariant as _FileVariant } from './FileVariant';
import type { FileVariantAttributes, FileVariantCreationAttributes } from './FileVariant';
import { NotificationDeliveryAttempt as _NotificationDeliveryAttempt } from './NotificationDeliveryAttempt';
import type {
	NotificationDeliveryAttemptAttributes,
	NotificationDeliveryAttemptCreationAttributes,
} from './NotificationDeliveryAttempt';
import { NotificationDevice as _NotificationDevice } from './NotificationDevice';
import type { NotificationDeviceAttributes, NotificationDeviceCreationAttributes } from './NotificationDevice';
import { NotificationMessage as _NotificationMessage } from './NotificationMessage';
import type { NotificationMessageAttributes, NotificationMessageCreationAttributes } from './NotificationMessage';
import { NotificationPreference as _NotificationPreference } from './NotificationPreference';
import type {
	NotificationPreferenceAttributes,
	NotificationPreferenceCreationAttributes,
} from './NotificationPreference';
import { NotificationReceipt as _NotificationReceipt } from './NotificationReceipt';
import type { NotificationReceiptAttributes, NotificationReceiptCreationAttributes } from './NotificationReceipt';
import { PasswordResetToken as _PasswordResetToken } from './PasswordResetToken';
import type { PasswordResetTokenAttributes, PasswordResetTokenCreationAttributes } from './PasswordResetToken';
import { Permission as _Permission } from './Permission';
import type { PermissionAttributes, PermissionCreationAttributes } from './Permission';
import { RefreshTokenAuditLog as _RefreshTokenAuditLog } from './RefreshTokenAuditLog';
import type { RefreshTokenAuditLogAttributes, RefreshTokenAuditLogCreationAttributes } from './RefreshTokenAuditLog';
import { RefreshTokenAuditLogsDefault as _RefreshTokenAuditLogsDefault } from './RefreshTokenAuditLogsDefault';
import type {
	RefreshTokenAuditLogsDefaultAttributes,
	RefreshTokenAuditLogsDefaultCreationAttributes,
} from './RefreshTokenAuditLogsDefault';
import { Role as _Role } from './Role';
import type { RoleAttributes, RoleCreationAttributes } from './Role';
import { RolePermission as _RolePermission } from './RolePermission';
import type { RolePermissionAttributes, RolePermissionCreationAttributes } from './RolePermission';
import { SchemaMigration as _SchemaMigration } from './SchemaMigration';
import type { SchemaMigrationAttributes, SchemaMigrationCreationAttributes } from './SchemaMigration';
import { SystemAuditLog as _SystemAuditLog } from './SystemAuditLog';
import type { SystemAuditLogAttributes, SystemAuditLogCreationAttributes } from './SystemAuditLog';
import { SystemAuditLogsDefault as _SystemAuditLogsDefault } from './SystemAuditLogsDefault';
import type {
	SystemAuditLogsDefaultAttributes,
	SystemAuditLogsDefaultCreationAttributes,
} from './SystemAuditLogsDefault';
import { User as _User } from './User';
import type { UserAttributes, UserCreationAttributes } from './User';
import { UserAuth as _UserAuth } from './UserAuth';
import type { UserAuthAttributes, UserAuthCreationAttributes } from './UserAuth';
import { UserPasswordHistory as _UserPasswordHistory } from './UserPasswordHistory';
import type { UserPasswordHistoryAttributes, UserPasswordHistoryCreationAttributes } from './UserPasswordHistory';
import { UserRole as _UserRole } from './UserRole';
import type { UserRoleAttributes, UserRoleCreationAttributes } from './UserRole';
import { UserRoleDetail as _UserRoleDetail } from './UserRoleDetail';
import type { UserRoleDetailAttributes, UserRoleDetailCreationAttributes } from './UserRoleDetail';
import { UserSession as _UserSession } from './UserSession';
import type { UserSessionAttributes, UserSessionCreationAttributes } from './UserSession';
import { UserSessionsDetailed as _UserSessionsDetailed } from './UserSessionsDetailed';
import type { UserSessionsDetailedAttributes, UserSessionsDetailedCreationAttributes } from './UserSessionsDetailed';
import { WebhookLog as _WebhookLog } from './WebhookLog';
import type { WebhookLogAttributes, WebhookLogCreationAttributes } from './WebhookLog';

export type InitModels = ReturnType<typeof initModels>;

export function initModels(sequelize: Sequelize) {
	const AuditDeadLetter = _AuditDeadLetter.initModel(sequelize);
	const AuditOutbox = _AuditOutbox.initModel(sequelize);
	const AuthAuditLog = _AuthAuditLog.initModel(sequelize);
	const AuthAuditLogsDefault = _AuthAuditLogsDefault.initModel(sequelize);
	const Client = _Client.initModel(sequelize);
	const EmailVerifyToken = _EmailVerifyToken.initModel(sequelize);
	const EntityChangeLog = _EntityChangeLog.initModel(sequelize);
	const EntityChangeLogsDefault = _EntityChangeLogsDefault.initModel(sequelize);
	const File = _File.initModel(sequelize);
	const FileVariant = _FileVariant.initModel(sequelize);
	const NotificationDeliveryAttempt = _NotificationDeliveryAttempt.initModel(sequelize);
	const NotificationDevice = _NotificationDevice.initModel(sequelize);
	const NotificationMessage = _NotificationMessage.initModel(sequelize);
	const NotificationPreference = _NotificationPreference.initModel(sequelize);
	const NotificationReceipt = _NotificationReceipt.initModel(sequelize);
	const PasswordResetToken = _PasswordResetToken.initModel(sequelize);
	const Permission = _Permission.initModel(sequelize);
	const RefreshTokenAuditLog = _RefreshTokenAuditLog.initModel(sequelize);
	const RefreshTokenAuditLogsDefault = _RefreshTokenAuditLogsDefault.initModel(sequelize);
	const Role = _Role.initModel(sequelize);
	const RolePermission = _RolePermission.initModel(sequelize);
	const SchemaMigration = _SchemaMigration.initModel(sequelize);
	const SystemAuditLog = _SystemAuditLog.initModel(sequelize);
	const SystemAuditLogsDefault = _SystemAuditLogsDefault.initModel(sequelize);
	const User = _User.initModel(sequelize);
	const UserAuth = _UserAuth.initModel(sequelize);
	const UserPasswordHistory = _UserPasswordHistory.initModel(sequelize);
	const UserRole = _UserRole.initModel(sequelize);
	const UserRoleDetail = _UserRoleDetail.initModel(sequelize);
	const UserSession = _UserSession.initModel(sequelize);
	const UserSessionsDetailed = _UserSessionsDetailed.initModel(sequelize);
	const WebhookLog = _WebhookLog.initModel(sequelize);

	// --- Audit log relationships ---
	AuthAuditLog.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(AuthAuditLog, { as: 'auth_audit_logs', foreignKey: 'user_id' });
	AuthAuditLogsDefault.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(AuthAuditLogsDefault, { as: 'auth_audit_logs_defaults', foreignKey: 'user_id' });
	EntityChangeLog.belongsTo(User, { as: 'actor', foreignKey: 'actor_id' });
	User.hasMany(EntityChangeLog, { as: 'entity_change_logs', foreignKey: 'actor_id' });
	EntityChangeLogsDefault.belongsTo(User, { as: 'actor', foreignKey: 'actor_id' });
	User.hasMany(EntityChangeLogsDefault, { as: 'entity_change_logs_defaults', foreignKey: 'actor_id' });
	RefreshTokenAuditLog.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(RefreshTokenAuditLog, { as: 'refresh_token_audit_logs', foreignKey: 'user_id' });
	RefreshTokenAuditLogsDefault.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(RefreshTokenAuditLogsDefault, { as: 'refresh_token_audit_logs_defaults', foreignKey: 'user_id' });
	SystemAuditLog.belongsTo(User, { as: 'actor', foreignKey: 'actor_id' });
	User.hasMany(SystemAuditLog, { as: 'system_audit_logs', foreignKey: 'actor_id' });
	SystemAuditLogsDefault.belongsTo(User, { as: 'actor', foreignKey: 'actor_id' });
	User.hasMany(SystemAuditLogsDefault, { as: 'system_audit_logs_defaults', foreignKey: 'actor_id' });

	// --- Files ---
	FileVariant.belongsTo(File, { as: 'file', foreignKey: 'file_id' });
	File.hasMany(FileVariant, { as: 'file_variants', foreignKey: 'file_id' });
	User.belongsTo(File, { as: 'avatar', foreignKey: 'avatar_id' });
	File.hasMany(User, { as: 'users', foreignKey: 'avatar_id' });
	File.belongsTo(User, { as: 'created_by_user', foreignKey: 'created_by' });
	User.hasMany(File, { as: 'files', foreignKey: 'created_by' });
	File.belongsTo(User, { as: 'deleted_by_user', foreignKey: 'deleted_by' });
	User.hasMany(File, { as: 'deleted_by_files', foreignKey: 'deleted_by' });
	File.belongsTo(User, { as: 'owner_user', foreignKey: 'owner_user_id' });
	User.hasMany(File, { as: 'owner_user_files', foreignKey: 'owner_user_id' });
	File.belongsTo(User, { as: 'updated_by_user', foreignKey: 'updated_by' });
	User.hasMany(File, { as: 'updated_by_files', foreignKey: 'updated_by' });

	// --- Notifications ---
	NotificationDeliveryAttempt.belongsTo(NotificationDevice, { as: 'device', foreignKey: 'device_id' });
	NotificationDevice.hasMany(NotificationDeliveryAttempt, {
		as: 'notification_delivery_attempts',
		foreignKey: 'device_id',
	});
	NotificationReceipt.belongsTo(NotificationMessage, { as: 'message', foreignKey: 'message_id' });
	NotificationMessage.hasMany(NotificationReceipt, { as: 'notification_receipts', foreignKey: 'message_id' });
	NotificationDeliveryAttempt.belongsTo(NotificationReceipt, { as: 'receipt', foreignKey: 'receipt_id' });
	NotificationReceipt.hasMany(NotificationDeliveryAttempt, {
		as: 'notification_delivery_attempts',
		foreignKey: 'receipt_id',
	});
	NotificationDevice.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(NotificationDevice, { as: 'notification_devices', foreignKey: 'user_id' });
	NotificationPreference.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(NotificationPreference, { as: 'notification_preferences', foreignKey: 'user_id' });
	NotificationReceipt.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(NotificationReceipt, { as: 'notification_receipts', foreignKey: 'user_id' });

	// --- RBAC ---
	RolePermission.belongsTo(Permission, { as: 'permission', foreignKey: 'permission_id' });
	Permission.hasMany(RolePermission, { as: 'role_permissions', foreignKey: 'permission_id' });
	RolePermission.belongsTo(Role, { as: 'role', foreignKey: 'role_id' });
	Role.hasMany(RolePermission, { as: 'role_permissions', foreignKey: 'role_id' });
	UserRole.belongsTo(Role, { as: 'role', foreignKey: 'role_id' });
	Role.hasMany(UserRole, { as: 'user_roles', foreignKey: 'role_id' });

	// --- Auth (tokens + sessions + history) ---
	EmailVerifyToken.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(EmailVerifyToken, { as: 'email_verify_tokens', foreignKey: 'user_id' });
	PasswordResetToken.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(PasswordResetToken, { as: 'password_reset_tokens', foreignKey: 'user_id' });
	Permission.belongsTo(User, { as: 'created_by_user', foreignKey: 'created_by' });
	User.hasMany(Permission, { as: 'permissions', foreignKey: 'created_by' });
	Permission.belongsTo(User, { as: 'updated_by_user', foreignKey: 'updated_by' });
	User.hasMany(Permission, { as: 'updated_by_permissions', foreignKey: 'updated_by' });
	RolePermission.belongsTo(User, { as: 'created_by_user', foreignKey: 'created_by' });
	User.hasMany(RolePermission, { as: 'role_permissions', foreignKey: 'created_by' });
	RolePermission.belongsTo(User, { as: 'updated_by_user', foreignKey: 'updated_by' });
	User.hasMany(RolePermission, { as: 'updated_by_role_permissions', foreignKey: 'updated_by' });
	Role.belongsTo(User, { as: 'created_by_user', foreignKey: 'created_by' });
	User.hasMany(Role, { as: 'roles', foreignKey: 'created_by' });
	Role.belongsTo(User, { as: 'updated_by_user', foreignKey: 'updated_by' });
	User.hasMany(Role, { as: 'updated_by_roles', foreignKey: 'updated_by' });
	UserAuth.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasOne(UserAuth, { as: 'user_auth', foreignKey: 'user_id' });
	UserPasswordHistory.belongsTo(User, { as: 'changed_by_user', foreignKey: 'changed_by' });
	User.hasMany(UserPasswordHistory, { as: 'user_password_histories', foreignKey: 'changed_by' });
	UserPasswordHistory.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(UserPasswordHistory, { as: 'user_user_password_histories', foreignKey: 'user_id' });
	UserRole.belongsTo(User, { as: 'assigned_by_user', foreignKey: 'assigned_by' });
	User.hasMany(UserRole, { as: 'user_roles', foreignKey: 'assigned_by' });
	UserRole.belongsTo(User, { as: 'created_by_user', foreignKey: 'created_by' });
	User.hasMany(UserRole, { as: 'created_by_user_roles', foreignKey: 'created_by' });
	UserRole.belongsTo(User, { as: 'updated_by_user', foreignKey: 'updated_by' });
	User.hasMany(UserRole, { as: 'updated_by_user_roles', foreignKey: 'updated_by' });
	UserRole.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(UserRole, { as: 'user_user_roles', foreignKey: 'user_id' });
	UserSession.belongsTo(User, { as: 'user', foreignKey: 'user_id' });
	User.hasMany(UserSession, { as: 'user_sessions', foreignKey: 'user_id' });

	// --- Self-referential User audit fields ---
	User.belongsTo(User, { as: 'created_by_user', foreignKey: 'created_by' });
	User.hasMany(User, { as: 'users', foreignKey: 'created_by' });
	User.belongsTo(User, { as: 'updated_by_user', foreignKey: 'updated_by' });
	User.hasMany(User, { as: 'updated_by_users', foreignKey: 'updated_by' });

	return {
		AuditDeadLetter,
		AuditOutbox,
		AuthAuditLog,
		AuthAuditLogsDefault,
		Client,
		EmailVerifyToken,
		EntityChangeLog,
		EntityChangeLogsDefault,
		File,
		FileVariant,
		NotificationDeliveryAttempt,
		NotificationDevice,
		NotificationMessage,
		NotificationPreference,
		NotificationReceipt,
		PasswordResetToken,
		Permission,
		RefreshTokenAuditLog,
		RefreshTokenAuditLogsDefault,
		Role,
		RolePermission,
		SchemaMigration,
		SystemAuditLog,
		SystemAuditLogsDefault,
		User,
		UserAuth,
		UserPasswordHistory,
		UserRole,
		UserRoleDetail,
		UserSession,
		UserSessionsDetailed,
		WebhookLog,
	};
}