import * as Sequelize from 'sequelize';
import { DataTypes, Model, Optional } from 'sequelize';
import type { User, UserId } from './User';
export interface UserSessionAttributes {
	id: string;
	user_id: string;
	token_version?: number | null;
	status?: 'active' | 'revoked' | 'expired' | 'logged_out' | null;
	device_info?: object | null;
	ip_address?: string | null;
	user_agent?: string | null;
	expires_at: Date;
	refresh_expires_at: Date;
	created_at?: Date | null;
	updated_at?: Date | null;
	last_activity_at?: Date | null;
	platform?: 'web' | 'mobile' | 'zalo_miniapp' | 'internal' | null;
	device_id?: string | null;
	device_name?: string | null;
	revoked_at?: Date | null;
	logged_out_at?: Date | null;
	tenant_id?: string | null;
	refresh_token_hash?: string | null;
	access_token_hash?: string | null;
}
export type UserSessionPk = 'id';
export type UserSessionId = UserSession[UserSessionPk];
export type UserSessionOptionalAttributes =
	| 'id'
	| 'token_version'
	| 'status'
	| 'device_info'
	| 'ip_address'
	| 'user_agent'
	| 'created_at'
	| 'updated_at'
	| 'last_activity_at'
	| 'platform'
	| 'device_id'
	| 'device_name'
	| 'revoked_at'
	| 'logged_out_at'
	| 'tenant_id'
	| 'refresh_token_hash'
	| 'access_token_hash';
export type UserSessionCreationAttributes = Optional<UserSessionAttributes, UserSessionOptionalAttributes>;
export class UserSession extends Model<UserSessionAttributes> implements UserSessionAttributes {
	declare id: string;
	declare user_id: string;
	declare token_version?: number | null;
	declare status?: 'active' | 'revoked' | 'expired' | 'logged_out' | null;
	declare device_info?: object | null;
	declare ip_address?: string | null;
	declare user_agent?: string | null;
	declare expires_at: Date;
	declare refresh_expires_at: Date;
	declare created_at?: Date | null;
	declare updated_at?: Date | null;
	declare last_activity_at?: Date | null;
	declare platform?: 'web' | 'mobile' | 'zalo_miniapp' | 'internal' | null;
	declare device_id?: string | null;
	declare device_name?: string | null;
	declare revoked_at?: Date | null;
	declare logged_out_at?: Date | null;
	declare tenant_id?: string | null;
	declare refresh_token_hash?: string | null;
	declare access_token_hash?: string | null;
	// UserSession belongsTo User via user_id
	declare user: User;
	declare getUser: Sequelize.BelongsToGetAssociationMixin<User>;
	declare setUser: Sequelize.BelongsToSetAssociationMixin<User, UserId>;
	declare createUser: Sequelize.BelongsToCreateAssociationMixin<User>;
	static initModel(sequelize: Sequelize.Sequelize): typeof UserSession {
		return UserSession.init(
			{
				id: {
					type: DataTypes.UUID,
					allowNull: false,
					defaultValue: DataTypes.UUIDV4,
					primaryKey: true,
				},
				user_id: {
					type: DataTypes.UUID,
					allowNull: false,
					references: {
						model: 'users',
						key: 'id',
					},
				},
				token_version: {
					type: DataTypes.INTEGER,
					allowNull: true,
					defaultValue: 1,
				},
				status: {
					type: DataTypes.ENUM('active', 'revoked', 'expired', 'logged_out'),
					allowNull: true,
					defaultValue: 'active',
					comment: 'Session status: active, revoked, expired, logged_out',
				},
				device_info: {
					type: DataTypes.JSONB,
					allowNull: true,
					comment: 'Device information: OS, browser, type (for login history)',
				},
				ip_address: {
					type: DataTypes.INET,
					allowNull: true,
				},
				user_agent: {
					type: DataTypes.TEXT,
					allowNull: true,
				},
				expires_at: {
					type: DataTypes.DATE,
					allowNull: false,
				},
				refresh_expires_at: {
					type: DataTypes.DATE,
					allowNull: false,
				},
				created_at: {
					type: DataTypes.DATE,
					allowNull: true,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
				updated_at: {
					type: DataTypes.DATE,
					allowNull: true,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
				last_activity_at: {
					type: DataTypes.DATE,
					allowNull: true,
					defaultValue: Sequelize.Sequelize.literal('CURRENT_TIMESTAMP'),
				},
				platform: {
					type: DataTypes.ENUM('web', 'mobile', 'zalo_miniapp', 'internal'),
					allowNull: true,
					comment: 'Platform type: web, mobile, zalo_miniapp, internal',
				},
				device_id: {
					type: DataTypes.STRING(255),
					allowNull: true,
					comment: 'Unique device identifier',
				},
				device_name: {
					type: DataTypes.STRING(255),
					allowNull: true,
					comment: 'Human-readable device name',
				},
				revoked_at: {
					type: DataTypes.DATE,
					allowNull: true,
					comment: 'Timestamp when session was revoked (security event)',
				},
				logged_out_at: {
					type: DataTypes.DATE,
					allowNull: true,
					comment: 'Timestamp when user logged out',
				},
				tenant_id: {
					type: DataTypes.UUID,
					allowNull: true,
					comment: 'Tenant ID for multi-tenant support',
				},
				refresh_token_hash: {
					type: DataTypes.STRING(64),
					allowNull: true,
					comment: 'SHA-256 hash of plain refresh token for O(1) lookup during token rotation',
				},
				access_token_hash: {
					type: DataTypes.STRING(64),
					allowNull: true,
					comment: 'SHA-256 hash of plain access token for O(1) session validation',
				},
			},
			{
				sequelize,
				tableName: 'user_sessions',
				schema: 'public',
				timestamps: false,
				indexes: [
					{
						name: 'idx_user_sessions_access_token_hash',
						unique: true,
						fields: [{ name: 'access_token_hash' }],
					},
					{
						name: 'idx_user_sessions_expires_at',
						fields: [{ name: 'expires_at' }],
					},
					{
						name: 'idx_user_sessions_refresh_token_hash',
						unique: true,
						fields: [{ name: 'refresh_token_hash' }],
					},
					{
						name: 'idx_user_sessions_status',
						fields: [{ name: 'status' }],
					},
					{
						name: 'idx_user_sessions_user_id',
						fields: [{ name: 'user_id' }],
					},
					{
						name: 'user_sessions_pkey',
						unique: true,
						fields: [{ name: 'id' }],
					},
				],
			},
		);
	}
}
