using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; namespace MotoresArgentinosV2.Core.Entities; public class Brand { public int BrandID { get; set; } public int VehicleTypeID { get; set; } public string Name { get; set; } = string.Empty; public int? LegacyID { get; set; } } public class Model { public int ModelID { get; set; } public int BrandID { get; set; } public string Name { get; set; } = string.Empty; public int? LegacyID { get; set; } } public enum UserMigrationStatus : byte { LegacyPending = 0, MigratedActive = 1 } public enum AdStatusEnum { Draft = 1, PaymentPending = 2, ModerationPending = 3, Active = 4, Rejected = 5, Paused = 6, Sold = 7, Expired = 8, Deleted = 9, Reserved = 10 } public static class AdStatusHelper { public static string GetStatusDisplayName(int statusId) { return statusId switch { 1 => "Borrador", 2 => "Pago Pendiente", 3 => "En Revisión", 4 => "Activo", 5 => "Rechazado", 6 => "Pausado", 7 => "Vendido", 8 => "Vencido", 9 => "Eliminado", 10 => "Reservado", _ => "Desconocido" }; } } public class User { public int UserID { get; set; } public string UserName { get; set; } = string.Empty; public string Email { get; set; } = string.Empty; public string PasswordHash { get; set; } = string.Empty; public string? PasswordSalt { get; set; } public byte MigrationStatus { get; set; } public string? FirstName { get; set; } public string? LastName { get; set; } public string? PhoneNumber { get; set; } public byte UserType { get; set; } = 1; // 1: Particular, 3: Admin public string? MFASecret { get; set; } public bool IsMFAEnabled { get; set; } // Email Verification public bool IsEmailVerified { get; set; } public string? VerificationToken { get; set; } public DateTime? VerificationTokenExpiresAt { get; set; } public DateTime? LastVerificationEmailSentAt { get; set; } // Password Reset public string? PasswordResetToken { get; set; } public DateTime? PasswordResetTokenExpiresAt { get; set; } public DateTime? LastPasswordResetEmailSentAt { get; set; } // Para cambio de email public string? NewEmailCandidate { get; set; } public string? EmailChangeToken { get; set; } public DateTime? EmailChangeTokenExpiresAt { get; set; } // Para reset/desactivación de MFA public string? SecurityActionToken { get; set; } public DateTime? SecurityActionTokenExpiresAt { get; set; } // Bloqueo de usuario public bool IsBlocked { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // Relación con Refresh Tokens public ICollection RefreshTokens { get; set; } = new List(); // Notificaciones de recordatorio de mensajes no leídos public DateTime? LastUnreadMessageReminderSentAt { get; set; } } public class AuditLog { public int AuditLogID { get; set; } public string Action { get; set; } = string.Empty; public string Entity { get; set; } = string.Empty; public int EntityID { get; set; } public int UserID { get; set; } public string Details { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } public class Ad { public int AdID { get; set; } public int UserID { get; set; } public User User { get; set; } = null!; public int VehicleTypeID { get; set; } public int BrandID { get; set; } public Brand Brand { get; set; } = null!; public int ModelID { get; set; } public Model Model { get; set; } = null!; public string? VersionName { get; set; } public int Year { get; set; } public int KM { get; set; } public string? FuelType { get; set; } public string? Color { get; set; } public string? Segment { get; set; } public decimal Price { get; set; } public string Currency { get; set; } = "USD"; public string? Description { get; set; } public string? Location { get; set; } public string? Condition { get; set; } public int? DoorCount { get; set; } public string? Transmission { get; set; } public string? Steering { get; set; } public string? ContactPhone { get; set; } public string? ContactEmail { get; set; } public bool DisplayContactInfo { get; set; } = true; public bool ShowPhone { get; set; } = true; public bool AllowWhatsApp { get; set; } = true; public bool ShowEmail { get; set; } = true; public bool IsFeatured { get; set; } public int StatusID { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? PublishedAt { get; set; } public DateTime? ExpiresAt { get; set; } public int? LegacyAdID { get; set; } public DateTime? DeletedAt { get; set; } public int ViewsCounter { get; set; } public ICollection Photos { get; set; } = new List(); public ICollection Features { get; set; } = new List(); public ICollection Messages { get; set; } = new List(); // CAMPOS DE CONTROL DE NOTIFICACIONES public DateTime? LastPerformanceEmailSentAt { get; set; } // Para el resumen semanal public DateTime? PaymentReminderSentAt { get; set; } // Para carrito abandonado public bool ExpirationWarningSent { get; set; } // Para aviso por vencer } public class AdPhoto { public int PhotoID { get; set; } public int AdID { get; set; } public string FilePath { get; set; } = string.Empty; public bool IsCover { get; set; } public int SortOrder { get; set; } public Ad Ad { get; set; } = null!; } public class AdFeature { public int AdID { get; set; } public string FeatureKey { get; set; } = string.Empty; public string? FeatureValue { get; set; } } public class TransactionRecord { public int TransactionID { get; set; } public int AdID { get; set; } public Ad Ad { get; set; } = null!; public string OperationCode { get; set; } = string.Empty; public int PaymentMethodID { get; set; } public decimal Amount { get; set; } public string Status { get; set; } = "PENDING"; public string? ProviderPaymentId { get; set; } public string? ProviderResponse { get; set; } public string? SnapshotUserEmail { get; set; } public string? SnapshotUserName { get; set; } public string? SnapshotAdTitle { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? UpdatedAt { get; set; } } public class Favorite { public int UserID { get; set; } public int AdID { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } public class ChatMessage { [Key] public int MessageID { get; set; } public int AdID { get; set; } [ForeignKey("AdID")] [JsonIgnore] public Ad? Ad { get; set; } public int SenderID { get; set; } public int ReceiverID { get; set; } public string MessageText { get; set; } = string.Empty; public DateTime SentAt { get; set; } = DateTime.UtcNow; public bool IsRead { get; set; } = false; } public class PaymentMethod { public int PaymentMethodID { get; set; } public string Name { get; set; } = string.Empty; } public class AdViewLog { public int Id { get; set; } public int AdID { get; set; } public string IPAddress { get; set; } = string.Empty; public DateTime ViewDate { get; set; } = DateTime.UtcNow; } /// /// Categorías de correo disponibles para preferencias de notificación. /// public static class NotificationCategory { public const string Sistema = "sistema"; // Avisos del sistema (vencimientos, pagos) public const string Marketing = "marketing"; // Boletines y promociones public const string Rendimiento = "rendimiento"; // Resumen semanal de visitas/favoritos public const string Mensajes = "mensajes"; // Recordatorio de mensajes no leídos public static readonly string[] Todos = [Sistema, Marketing, Rendimiento, Mensajes]; } /// /// Preferencia de notificación por email de un usuario para una categoría específica. /// Por defecto el usuario recibe todos los correos; el registro solo se crea al DESACTIVAR. /// public class UserNotificationPreference { public int PreferenceID { get; set; } public int UserID { get; set; } public User User { get; set; } = null!; // Categoría: "sistema", "marketing", "rendimiento", "mensajes" public string Category { get; set; } = string.Empty; // false = usuario optó por NO recibir esta categoría public bool IsEnabled { get; set; } = true; public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; } /// /// Token de baja firmado con HMAC-SHA256 para darse de baja sin login. /// El token incluye UserID + Category y es válido hasta ExpiresAt. /// public class UnsubscribeToken { public int TokenID { get; set; } public int UserID { get; set; } public User User { get; set; } = null!; // Categoría a la que aplica el token public string Category { get; set; } = string.Empty; // Token opaco (GUID + HMAC) que va en el enlace del correo public string Token { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // Tokens de baja expiran a los 365 días (la URL del correo puede ser vieja) public DateTime ExpiresAt { get; set; } = DateTime.UtcNow.AddDays(365); // true cuando ya fue utilizado para darse de baja public bool IsUsed { get; set; } = false; }