using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace QuestionsApi.Models; public static class FlashcardTypes { public const string Basic = "basic"; public const string Cloze = "cloze"; public static readonly HashSet All = [Basic, Cloze]; } public static class FlashcardRatings { public const string Again = "again"; public const string Hard = "hard"; public const string Good = "good"; public const string Easy = "easy"; public static readonly string[] All = [Again, Hard, Good, Easy]; } public static class FlashcardScheduleStates { public const string New = "new"; public const string Learning = "learning"; public const string Review = "review"; public const string Relearning = "relearning"; } public sealed class FlashcardDeck { [BsonId, BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } public string UserId { get; set; } = ""; public string StableId { get; set; } = Guid.NewGuid().ToString(); public string Name { get; set; } = ""; public string NormalizedName { get; set; } = ""; public string Description { get; set; } = ""; public bool IsDefault { get; set; } public int? NewCardsPerDay { get; set; } public int? ReviewsPerDay { get; set; } public double? DesiredRetention { get; set; } public long Revision { get; set; } = 1; public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; public DateTime UpdatedUtc { get; set; } = DateTime.UtcNow; public DateTime? ArchivedUtc { get; set; } } public sealed class FlashcardImageReference { public string Kind { get; set; } = "owned"; public string AssetId { get; set; } = ""; } public sealed class FlashcardNote { [BsonId, BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } public string UserId { get; set; } = ""; public string StableId { get; set; } = Guid.NewGuid().ToString(); public string DeckId { get; set; } = ""; public string Type { get; set; } = FlashcardTypes.Basic; public string Prompt { get; set; } = ""; public string Answer { get; set; } = ""; public string Extra { get; set; } = ""; public List Tags { get; set; } = []; public List Images { get; set; } = []; public string SourceQuestionExternalId { get; set; } = ""; public string ContentFingerprint { get; set; } = ""; public long Revision { get; set; } = 1; public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; public DateTime UpdatedUtc { get; set; } = DateTime.UtcNow; public DateTime? ArchivedUtc { get; set; } } public sealed class FlashcardSchedule { [BsonId, BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } public string UserId { get; set; } = ""; public string NoteId { get; set; } = ""; public int Variant { get; set; } public string State { get; set; } = FlashcardScheduleStates.New; public int? Step { get; set; } public double? Stability { get; set; } public double? Difficulty { get; set; } public DateTime DueUtc { get; set; } = DateTime.UtcNow; public DateTime? LastReviewUtc { get; set; } public DateTime? BuriedUntilUtc { get; set; } public bool IsSuspended { get; set; } public long Revision { get; set; } = 1; public string AlgorithmVersion { get; set; } = "fsrs-core-1.0.7"; public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; } public sealed class FlashcardReviewLog { [BsonId] public string Id { get; set; } = ""; public string UserId { get; set; } = ""; public string CardId { get; set; } = ""; public string Rating { get; set; } = ""; public DateTime ReviewedUtc { get; set; } public int DurationSeconds { get; set; } public FlashcardScheduleSnapshot Before { get; set; } = new(); public FlashcardScheduleSnapshot After { get; set; } = new(); public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; public DateTime? UndoneUtc { get; set; } } public sealed class FlashcardScheduleSnapshot { public string State { get; set; } = FlashcardScheduleStates.New; public int? Step { get; set; } public double? Stability { get; set; } public double? Difficulty { get; set; } public DateTime DueUtc { get; set; } public DateTime? LastReviewUtc { get; set; } public long Revision { get; set; } } public sealed class FlashcardMediaAsset { [BsonId, BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } public string UserId { get; set; } = ""; public string FileName { get; set; } = ""; public string ContentType { get; set; } = ""; public byte[] Bytes { get; set; } = []; public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; } public sealed class FlashcardSettings { [BsonId, BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } public string UserId { get; set; } = ""; public int NewCardsPerDay { get; set; } = 20; public int ReviewsPerDay { get; set; } = 200; public double DesiredRetention { get; set; } = 0.90; public long Revision { get; set; } = 1; public DateTime UpdatedUtc { get; set; } = DateTime.UtcNow; } public sealed class UpsertFlashcardDeckRequest { public string Name { get; set; } = ""; public string Description { get; set; } = ""; public int? NewCardsPerDay { get; set; } public int? ReviewsPerDay { get; set; } public double? DesiredRetention { get; set; } public long? ExpectedRevision { get; set; } } public sealed class UpsertFlashcardNoteRequest { public string DeckId { get; set; } = ""; public string StableId { get; set; } = ""; public string Type { get; set; } = FlashcardTypes.Basic; public string Prompt { get; set; } = ""; public string Answer { get; set; } = ""; public string Extra { get; set; } = ""; public List Tags { get; set; } = []; public List Images { get; set; } = []; public string SourceQuestionExternalId { get; set; } = ""; public long? ExpectedRevision { get; set; } } public sealed class UpdateFlashcardSettingsRequest { public int NewCardsPerDay { get; set; } = 20; public int ReviewsPerDay { get; set; } = 200; public double DesiredRetention { get; set; } = 0.90; public long? ExpectedRevision { get; set; } } public sealed class FlashcardDeckSummary { public FlashcardDeck Deck { get; set; } = new(); public int Total { get; set; } public int Due { get; set; } public int New { get; set; } public int Suspended { get; set; } } public sealed class FlashcardLibraryResponse { public List Items { get; set; } = []; public int Total { get; set; } } public sealed class FlashcardLibraryQuery { public string? DeckId { get; set; } public string? Tag { get; set; } public string? Type { get; set; } public string? State { get; set; } public string? Search { get; set; } public int Page { get; set; } = 1; public int PageSize { get; set; } = 50; } public sealed class FlashcardStudyRequest { public string DeckId { get; set; } = ""; public List ExcludeCardIds { get; set; } = []; public DateTime StudyDayStartUtc { get; set; } = DateTime.UtcNow.Date; } public sealed class FlashcardBulkNoteIdsRequest { public List NoteIds { get; set; } = []; } public sealed class FlashcardMoveRequest { public List NoteIds { get; set; } = []; public string TargetDeckId { get; set; } = ""; } public sealed class FlashcardBatchReviewRequest { public List Reviews { get; set; } = []; } public sealed class FlashcardBatchReviewResponse { public List Results { get; set; } = []; } public sealed class FlashcardUndoRequest { public string ReviewLogId { get; set; } = ""; } public sealed class FlashcardRatingOption { public string Rating { get; set; } = ""; public string IntervalLabel { get; set; } = ""; public DateTime DueUtc { get; set; } } public sealed class FlashcardStudyCardResponse { public FlashcardNote? Note { get; set; } public FlashcardSchedule? Card { get; set; } public List RatingOptions { get; set; } = []; public int DueRemaining { get; set; } public int NewRemaining { get; set; } } public sealed class FlashcardReviewRequest { public string ClientReviewId { get; set; } = ""; public string CardId { get; set; } = ""; public string Rating { get; set; } = ""; public long ExpectedRevision { get; set; } public DateTime ReviewedUtc { get; set; } public int DurationSeconds { get; set; } public DateTime StudyDayStartUtc { get; set; } = DateTime.UtcNow.Date; } public sealed class FlashcardReviewResponse { public FlashcardSchedule Card { get; set; } = new(); public List RatingOptions { get; set; } = []; public bool Duplicate { get; set; } } public sealed class FlashcardDashboardCounts { public int Due { get; set; } public int NewAvailable { get; set; } public int ReviewedThisWeek { get; set; } } public static class FlashcardImportFormats { public const string Csv = "csv"; public const string Json = "json"; } public static class FlashcardImportRowActions { public const string Create = "create"; public const string Update = "update"; public const string Skip = "skip"; public const string Error = "error"; } public sealed class FlashcardImportPendingRecord { public int RowNumber { get; set; } public string Action { get; set; } = FlashcardImportRowActions.Create; public string? Error { get; set; } public string StableId { get; set; } = ""; public string DeckName { get; set; } = ""; public string Type { get; set; } = FlashcardTypes.Basic; public string Prompt { get; set; } = ""; public string Answer { get; set; } = ""; public string Extra { get; set; } = ""; public List Tags { get; set; } = []; public string SourceQuestionExternalId { get; set; } = ""; public List Cards { get; set; } = []; public List ReviewLogs { get; set; } = []; } public sealed class FlashcardImportPreview { [BsonId] public string Id { get; set; } = ""; public string UserId { get; set; } = ""; public string Format { get; set; } = FlashcardImportFormats.Csv; public List Records { get; set; } = []; public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; public DateTime ExpiresUtc { get; set; } = DateTime.UtcNow.AddHours(1); } public sealed class FlashcardImportPreviewRow { public int RowNumber { get; set; } public string Action { get; set; } = FlashcardImportRowActions.Create; public string? Error { get; set; } public string StableId { get; set; } = ""; public string Deck { get; set; } = ""; public string Type { get; set; } = FlashcardTypes.Basic; public string Prompt { get; set; } = ""; public string Answer { get; set; } = ""; } public sealed class FlashcardImportPreviewResponse { public string ImportToken { get; set; } = ""; public int CreateCount { get; set; } public int UpdateCount { get; set; } public int SkipCount { get; set; } public int ErrorCount { get; set; } public List Rows { get; set; } = []; } public sealed class FlashcardImportCommitRequest { public string ImportToken { get; set; } = ""; } public sealed class FlashcardImportCommitResponse { public int Created { get; set; } public int Updated { get; set; } public int Skipped { get; set; } public int Errored { get; set; } public List Errors { get; set; } = []; } public sealed class FlashcardExportOmission { public string Kind { get; set; } = ""; public string Reason { get; set; } = ""; } public sealed class FlashcardJsonExport { public int SchemaVersion { get; set; } = 1; public DateTime ExportedUtc { get; set; } = DateTime.UtcNow; public FlashcardSettings Settings { get; set; } = new(); public List Decks { get; set; } = []; public List Notes { get; set; } = []; } public sealed class FlashcardJsonExportNote { public FlashcardNote Note { get; set; } = new(); public List Cards { get; set; } = []; public List ReviewLogs { get; set; } = []; public List Images { get; set; } = []; } public sealed class FlashcardJsonExportImage { public string AssetId { get; set; } = ""; public string FileName { get; set; } = ""; public string ContentType { get; set; } = ""; public string Base64Bytes { get; set; } = ""; }