/// <summary>
        /// อัพเดทหรือเพิ่มข้อมูล Student key
        /// </summary>
        /// <param name="data">ข้อมูลที่ต้องการดำเนินการ</param>
        public void UpsertStudentKey(StudentKey data)
        {
            var update = Builders<StudentKey>.Update
               .Set(it => it.Code, data.Code)
               .Set(it => it.Grade, data.Grade)
               .Set(it => it.CourseCatalogId, data.CourseCatalogId)
               .Set(it => it.ClassRoomId, data.ClassRoomId)
               .Set(it => it.CreatedDate, data.CreatedDate)
               .Set(it => it.DeletedDate, data.DeletedDate);

            var updateOption = new UpdateOptions { IsUpsert = true };
            MongoAccess.MongoUtil.Instance.GetCollection<StudentKey>(TableName)
               .UpdateOne(it => it.id == data.id, update, updateOption);
        }
        public void Put(string id, UpdateCourseInfoRequest body)
        {
            var isArgumentValid = !string.IsNullOrEmpty(id)
                && body != null
                && !string.IsNullOrEmpty(body.ClassRoomId);
            if (!isArgumentValid) return;

            var userprofile = _userprofileRepo.GetUserProfileById(id);
            if (userprofile == null) return;

            var isUserprofileValid = userprofile.Subscriptions != null && userprofile.Subscriptions.Any();
            if (!isUserprofileValid) return;

            var isCanUpdateCourse = userprofile.Subscriptions.Any(it => !it.DeletedDate.HasValue && it.ClassRoomId == body.ClassRoomId && it.Role == UserProfile.AccountRole.Teacher);
            if (!isCanUpdateCourse) return;

            var selectedClassRoom = _classRoomRepo.GetClassRoomById(body.ClassRoomId);
            var canAccessCalssRoom = selectedClassRoom != null && !selectedClassRoom.DeletedDate.HasValue;
            if (!canAccessCalssRoom) return;

            var now = _dateTime.GetCurrentTime();
            var isRequestUpdateStudentCode = !string.IsNullOrEmpty(body.ChangedStudentCode);
            if (isRequestUpdateStudentCode)
            {
                var selectedStudentKeyObj = _studentKeyRepo.GetStudentKeyByClassRoomId(body.ClassRoomId);
                if (selectedStudentKeyObj != null)
                {
                    if (!selectedStudentKeyObj.DeletedDate.HasValue)
                    {
                        selectedStudentKeyObj.DeletedDate = now;
                        _studentKeyRepo.UpsertStudentKey(selectedStudentKeyObj);
                    }

                    var newStudentKey = new StudentKey
                    {
                        id = Guid.NewGuid().ToString(),
                        Grade = selectedStudentKeyObj.Grade,
                        Code = body.ChangedStudentCode,
                        CourseCatalogId = selectedStudentKeyObj.CourseCatalogId,
                        ClassRoomId = selectedStudentKeyObj.ClassRoomId,
                        CreatedDate = now
                    };
                    _studentKeyRepo.CreateNewStudentKey(newStudentKey);
                }
            }

            var isRequestUpdateClassName = !string.IsNullOrEmpty(body.ClassName);
            if (isRequestUpdateClassName)
            {
                selectedClassRoom.Name = body.ClassName;
                _classRoomRepo.UpsertClassRoom(selectedClassRoom);
            }

            //if (body.BeginDate.HasValue)
            //{
            //    var classCalendar = _classCalendarRepo.GetClassCalendarByClassRoomId(body.ClassRoomId);
            //    var canUpdateClassCalendar = classCalendar != null;
            //    if (!canUpdateClassCalendar) return;

            //    classCalendar.BeginDate = body.BeginDate.Value;
            //    _classCalendarRepo.UpsertClassCalendar(classCalendar);
            //}
        }
        private bool addNewCourseByStudentCode(UserProfile selectedUserProfile, StudentKey selectedStudentKey, DateTime currentTime)
        {
            var canUserprofileAccessToTheClassRoom = selectedUserProfile.Subscriptions
                .Where(it => !it.DeletedDate.HasValue)
                .Any(it => it.ClassRoomId == selectedStudentKey.ClassRoomId);
            if (canUserprofileAccessToTheClassRoom) return false;

            var selectedClassRoom = _classRoomRepo.GetClassRoomById(selectedStudentKey.ClassRoomId);
            if (selectedClassRoom == null) return false;

            var selectedClassCalendar = _classCalendarRepo.GetClassCalendarByClassRoomId(selectedStudentKey.ClassRoomId);
            if (selectedClassCalendar == null) return false;

            var lessonCatalogs = selectedClassRoom.Lessons
                .Select(it => _lessonCatalogRepo.GetLessonCatalogById(it.LessonCatalogId))
                .ToList();
            if (lessonCatalogs.Any(it => it == null)) return false;

            var teacherSubscription = _userprofileRepo.GetUserProfilesByClassRoomId(selectedClassRoom.id)
                .Where(it => !it.DeletedDate.HasValue)
                .SelectMany(it => it.Subscriptions)
                .Where(it => !it.DeletedDate.HasValue)
                .Where(it => it.Role == UserProfile.AccountRole.Teacher)
                .Where(it => it.ClassRoomId == selectedClassRoom.id)
                .FirstOrDefault();
            if (teacherSubscription == null)
            {
                _logger.LogWarning($"Teacher account in the private ClassRoomId: { selectedStudentKey.ClassRoomId } not found.");
                return false;
            }

            selectedUserProfile.Subscriptions = createNewSubscription(selectedUserProfile.Subscriptions,
                UserProfile.AccountRole.Student,
                selectedClassRoom,
                selectedClassCalendar.id,
                teacherSubscription.LicenseId,
                currentTime);
            _userprofileRepo.UpsertUserProfile(selectedUserProfile);

            var userActivity = selectedUserProfile.CreateNewUserActivity(selectedClassRoom, selectedClassCalendar, lessonCatalogs, currentTime);
            _userActivityRepo.UpsertUserActivity(userActivity);

            return true;
        }
        private async Task<bool> addNewCourseByTeacherCode(string code, string grade, UserProfile selectedUserProfile, DateTime currentTime)
        {
            var selectedContract = await _contractRepo.GetContractsByTeacherCode(code, grade);
            var isTeacherKey = selectedContract != null
                && !selectedContract.DeletedDate.HasValue
                && selectedContract.Licenses.Any();
            if (!isTeacherKey) return false;

            var selectedLicense = selectedContract.Licenses
                .Where(it => !it.DeletedDate.HasValue)
                .FirstOrDefault(it => it.TeacherKeys.Any(t => !t.DeletedDate.HasValue && t.Code == code && t.Grade == grade));
            if (selectedLicense == null) return false;

            var selectedTeacherKey = selectedLicense.TeacherKeys
                .Where(it => !it.DeletedDate.HasValue)
                .OrderBy(it => it.CreatedDate)
                .LastOrDefault();
            if (selectedTeacherKey == null) return false;

            // Create new ClassRoom
            var selectedCourseCatalog = _courseCatalogRepo.GetCourseCatalogById(selectedLicense.CourseCatalogId);
            if (selectedCourseCatalog == null) return false;
            var lessonCatalogs = _lessonCatalogRepo.GetLessonCatalogByCourseCatalogId(selectedCourseCatalog.id).ToList();
            if (lessonCatalogs == null || !lessonCatalogs.Any()) return false;
            var lessons = lessonCatalogs
                .Where(it => !it.DeletedDate.HasValue)
                .Select(it => new ClassRoom.Lesson
                {
                    id = Guid.NewGuid().ToString(),
                    LessonCatalogId = it.id
                }).ToList();
            var newClassRoom = new ClassRoom
            {
                id = Guid.NewGuid().ToString(),
                Name = selectedCourseCatalog.SideName,
                CourseCatalogId = selectedCourseCatalog.id,
                CreatedDate = currentTime,
                LastUpdatedMessageDate = currentTime,
                Lessons = lessons
            };
            await _classRoomRepo.CreateNewClassRoom(newClassRoom);

            // Create new ClassCalendar
            var lessonCalendars = lessonCatalogs
                .Where(it => !it.DeletedDate.HasValue)
                .Select(lesson =>
                {
                    var selectedLesson = lessons.FirstOrDefault(it => it.LessonCatalogId == lesson.id);
                    return new ClassCalendar.LessonCalendar
                    {
                        id = Guid.NewGuid().ToString(),
                        Order = lesson.Order,
                        SemesterGroupName = lesson.SemesterName,
                        BeginDate = currentTime,
                        CreatedDate = currentTime,
                        LessonId = selectedLesson.id,
                        TopicOfTheDays = lesson.TopicOfTheDays
                            .Where(it => !it.DeletedDate.HasValue)
                            .Select(it => new ClassCalendar.TopicOfTheDay
                            {
                                id = it.id,
                                Message = it.Message,
                                SendOnDay = it.SendOnDay,
                                CreatedDate = currentTime,
                            })
                    };
                }).ToList();
            var newClassCalendar = new ClassCalendar
            {
                id = Guid.NewGuid().ToString(),
                ClassRoomId = newClassRoom.id,
                CreatedDate = currentTime,
                Holidays = Enumerable.Empty<DateTime>(),
                ShiftDays = Enumerable.Empty<DateTime>(),
                LessonCalendars = lessonCalendars
            };
            await _classCalendarRepo.CreateNewClassCalendar(newClassCalendar);

            // Create new UserActivity
            var userActivity = selectedUserProfile.CreateNewUserActivity(newClassRoom, newClassCalendar, lessonCatalogs, currentTime);
            _userActivityRepo.UpsertUserActivity(userActivity);

            // Create new subscription
            var subscriptions = createNewSubscription(selectedUserProfile.Subscriptions, UserProfile.AccountRole.Teacher, newClassRoom, newClassCalendar.id, selectedLicense.id, currentTime);
            selectedUserProfile.Subscriptions = subscriptions;
            _userprofileRepo.UpsertUserProfile(selectedUserProfile);

            // Create new student key
            var newStudentKey = new StudentKey
            {
                id = Guid.NewGuid().ToString(),
                Grade = grade,
                Code = generateStudentCode(grade),
                CourseCatalogId = selectedCourseCatalog.id,
                ClassRoomId = newClassRoom.id,
                CreatedDate = currentTime
            };

            await _studentKeyRepo.CreateNewStudentKey(newStudentKey);
            return true;
        }
 /// <summary>
 /// เพิ่มข้อมูล Student key ใหม่
 /// </summary>
 /// <param name="data">ข้อมูล Student key ที่ต้องการเพิ่ม</param>
 public async Task CreateNewStudentKey(StudentKey data)
 {
     await _mongoUtil.GetCollection<StudentKey>(TableName).InsertOneAsync(data);
 }