package repository import ( "narasi-ahli-be/app/database" "narasi-ahli-be/app/database/entity" "narasi-ahli-be/app/module/chat/request" "narasi-ahli-be/utils/paginator" ) type chatScheduleRepository struct { DB *database.Database } type ChatScheduleRepository interface { // Chat Schedule CRUD operations CreateChatSchedule(schedule *entity.ChatSchedules) (result *entity.ChatSchedules, err error) GetAllChatSchedules(userId uint, req request.ChatScheduleQueryRequest) (schedules []*entity.ChatSchedules, paging paginator.Pagination, err error) GetChatScheduleByID(id uint) (schedule *entity.ChatSchedules, err error) UpdateChatSchedule(id uint, schedule *entity.ChatSchedules) (err error) DeleteChatSchedule(id uint) (err error) // Chat Schedule File operations CreateChatScheduleFile(file *entity.ChatScheduleFiles) (result *entity.ChatScheduleFiles, err error) GetChatScheduleFilesByScheduleID(scheduleID uint) (files []*entity.ChatScheduleFiles, err error) UpdateChatScheduleFile(id uint, file *entity.ChatScheduleFiles) (err error) DeleteChatScheduleFile(id uint) (err error) // Utility methods CheckUserInChatSchedule(userId uint, scheduleID uint) (isParticipant bool, err error) GetUpcomingSchedules(userId uint, limit int) (schedules []*entity.ChatSchedules, err error) GetSchedulesByStatus(status string) (schedules []*entity.ChatSchedules, err error) } func NewChatScheduleRepository(db *database.Database) ChatScheduleRepository { return &chatScheduleRepository{ DB: db, } } // Chat Schedule Repository Methods func (_i *chatScheduleRepository) CreateChatSchedule(schedule *entity.ChatSchedules) (result *entity.ChatSchedules, err error) { err = _i.DB.DB.Create(schedule).Error if err != nil { return nil, err } err = _i.DB.DB.Preload("Creator"). Preload("ChatSession"). Preload("Files"). First(&result, schedule.ID).Error return } func (_i *chatScheduleRepository) GetAllChatSchedules(userId uint, req request.ChatScheduleQueryRequest) (schedules []*entity.ChatSchedules, paging paginator.Pagination, err error) { // Get chat schedules where user is a participant in the chat session query := _i.DB.DB.Model(&entity.ChatSchedules{}). Joins("INNER JOIN chat_sessions cs ON chat_schedules.chat_session_id = cs.id"). Joins("INNER JOIN chat_participants cp ON cs.id = cp.chat_session_id"). Where("cp.user_id = ? AND cp.is_active = true", userId) // Apply filters if req.ChatSessionID != nil { query = query.Where("chat_schedules.chat_session_id = ?", *req.ChatSessionID) } if req.Status != nil { query = query.Where("chat_schedules.status = ?", *req.Status) } if req.CreatedBy != nil { query = query.Where("chat_schedules.created_by = ?", *req.CreatedBy) } if req.DateFrom != nil { query = query.Where("DATE(chat_schedules.scheduled_at) >= ?", req.DateFrom.Format("2006-01-02")) } if req.DateTo != nil { query = query.Where("DATE(chat_schedules.scheduled_at) <= ?", req.DateTo.Format("2006-01-02")) } // Include relationships query = query.Preload("Creator"). Preload("ChatSession"). Preload("Files") // Order by scheduled_at asc (upcoming first) query = query.Order("chat_schedules.scheduled_at ASC") // Apply pagination var count int64 query.Count(&count) req.Pagination.Count = count pagingResult := paginator.Paging(&req.Pagination) err = query.Offset(pagingResult.Offset).Limit(pagingResult.Limit).Find(&schedules).Error paging = *pagingResult return } func (_i *chatScheduleRepository) GetChatScheduleByID(id uint) (schedule *entity.ChatSchedules, err error) { err = _i.DB.DB.Preload("Creator"). Preload("ChatSession"). Preload("Files"). First(&schedule, id).Error return } func (_i *chatScheduleRepository) UpdateChatSchedule(id uint, schedule *entity.ChatSchedules) (err error) { err = _i.DB.DB.Model(&entity.ChatSchedules{}).Where("id = ?", id).Updates(schedule).Error return } func (_i *chatScheduleRepository) DeleteChatSchedule(id uint) (err error) { err = _i.DB.DB.Delete(&entity.ChatSchedules{}, id).Error return } // Chat Schedule File Repository Methods func (_i *chatScheduleRepository) CreateChatScheduleFile(file *entity.ChatScheduleFiles) (result *entity.ChatScheduleFiles, err error) { err = _i.DB.DB.Create(file).Error if err != nil { return nil, err } err = _i.DB.DB.First(&result, file.ID).Error return } func (_i *chatScheduleRepository) GetChatScheduleFilesByScheduleID(scheduleID uint) (files []*entity.ChatScheduleFiles, err error) { err = _i.DB.DB.Model(&entity.ChatScheduleFiles{}).Where("chat_schedule_id = ?", scheduleID).Find(&files).Error return } func (_i *chatScheduleRepository) UpdateChatScheduleFile(id uint, file *entity.ChatScheduleFiles) (err error) { err = _i.DB.DB.Model(&entity.ChatScheduleFiles{}).Where("id = ?", id).Updates(file).Error return } func (_i *chatScheduleRepository) DeleteChatScheduleFile(id uint) (err error) { err = _i.DB.DB.Delete(&entity.ChatScheduleFiles{}, id).Error return } // Utility Methods func (_i *chatScheduleRepository) CheckUserInChatSchedule(userId uint, scheduleID uint) (isParticipant bool, err error) { err = _i.DB.DB.Model(&entity.ChatParticipants{}). Select("COUNT(*) > 0"). Joins("INNER JOIN chat_sessions cs ON chat_participants.chat_session_id = cs.id"). Where("cs.id = ? AND chat_participants.user_id = ? AND chat_participants.is_active = true", scheduleID, userId). Scan(&isParticipant).Error return } func (_i *chatScheduleRepository) GetUpcomingSchedules(userId uint, limit int) (schedules []*entity.ChatSchedules, err error) { err = _i.DB.DB.Model(&entity.ChatSchedules{}). Joins("INNER JOIN chat_sessions cs ON chat_schedules.chat_session_id = cs.id"). Joins("INNER JOIN chat_participants cp ON cs.id = cp.chat_session_id"). Where("cp.user_id = ? AND cp.is_active = true AND chat_schedules.scheduled_at > NOW() AND chat_schedules.status = 'scheduled'", userId). Preload("Creator"). Preload("ChatSession"). Preload("Files"). Order("chat_schedules.scheduled_at ASC"). Limit(limit). Find(&schedules).Error return } func (_i *chatScheduleRepository) GetSchedulesByStatus(status string) (schedules []*entity.ChatSchedules, err error) { err = _i.DB.DB.Model(&entity.ChatSchedules{}). Where("status = ?", status). Preload("Creator"). Preload("ChatSession"). Preload("Files"). Order("scheduled_at ASC"). Find(&schedules).Error return }