//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
//Copyright (C) 2024 HTWKalender support@htwkalender.de

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU Affero General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU Affero General Public License for more details.

//You should have received a copy of the GNU Affero General Public License
//along with this program.  If not, see <https://www.gnu.org/licenses/>.

package events

import (
	"github.com/pocketbase/pocketbase"
	"htwkalender/data-manager/model"
	"htwkalender/data-manager/service/db"
	"htwkalender/data-manager/service/functions"
	"log/slog"
)

// CourseService defines the methods to be implemented
type CourseService interface {
	GetAllCourses() []string
	GetAllCoursesForSemester(semester string) []model.SeminarGroup
	GetAllCoursesForSemesterWithEvents(semester string) ([]string, error)
	FindCourseByCourseName(courseName string) (model.SeminarGroup, error)
}

// PocketBaseCourseService is a struct that implements the CourseService interface
type PocketBaseCourseService struct {
	app *pocketbase.PocketBase
}

// NewPocketBaseCourseService creates a new PocketBaseCourseService
func NewPocketBaseCourseService(app *pocketbase.PocketBase) *PocketBaseCourseService {
	return &PocketBaseCourseService{app: app}
}

// GetAllCourses returns all courses
func (s *PocketBaseCourseService) GetAllCourses() []string {
	courseList, err := db.GetAllCourses(s.app)
	if err != nil {
		slog.Error("Could not get all courses", "error", err)
		return nil
	}

	return courseList
}

// GetAllCoursesForSemester returns all courses for a specific semester
func (s *PocketBaseCourseService) GetAllCoursesForSemester(semester string) []model.SeminarGroup {
	seminarGroups, err := db.GetAllCoursesForSemester(s.app, semester)
	if err != nil {
		slog.Error("Could not get all courses for semester", "error", err)
		return nil
	}
	return seminarGroups
}

// GetAllCoursesForSemesterWithEvents returns all courses for a specific semester with events
func (s *PocketBaseCourseService) GetAllCoursesForSemesterWithEvents(semester string) ([]string, error) {
	courses, err := db.GetAllCoursesForSemesterWithEvents(s.app, semester)
	if err != nil {
		return nil, err
	}
	// remove empty courses like " " or ""
	courses = removeEmptyCourses(courses)
	return courses, nil
}

// removeEmptyCourses removes empty courses from the list of courses
func removeEmptyCourses(courses []string) []string {
	var filteredCourses []string

	for _, course := range courses {
		if !functions.OnlyWhitespace(course) || len(course) != 0 {
			filteredCourses = append(filteredCourses, course)
		}
	}
	return filteredCourses
}

// FindCourseByCourseName returns a course by its name
func (s *PocketBaseCourseService) FindCourseByCourseName(courseName string) (model.SeminarGroup, error) {
	return db.FindCourseByCourseName(s.app, courseName)
}
