//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 db

import (
	"github.com/pocketbase/dbx"
	"github.com/pocketbase/pocketbase"
	"github.com/pocketbase/pocketbase/models"
	"htwkalender/data-manager/model"
	"log/slog"
)

func SaveGroups(seminarGroup []model.SeminarGroup, collection *models.Collection, app *pocketbase.PocketBase) ([]*models.Record, error) {
	var savedRecords []*models.Record
	var tobeSavedGroups []model.SeminarGroup
	var insertRecords []*models.Record

	for _, group := range seminarGroup {
		dbGroup, err := FindGroupByCourseAndSemester(group.Course, group.Semester, app)

		if dbGroup == nil && err.Error() == "sql: no rows in result set" {
			tobeSavedGroups = append(tobeSavedGroups, group)
		} else if err != nil {
			return nil, err
		}
	}

	// create record for each group that's not already in the database
	for _, group := range tobeSavedGroups {
		record := models.NewRecord(collection)
		record.Set("university", group.University)
		record.Set("shortcut", group.GroupShortcut)
		record.Set("groupId", group.GroupId)
		record.Set("course", group.Course)
		record.Set("faculty", group.Faculty)
		record.Set("facultyId", group.FacultyId)
		record.Set("semester", group.Semester)
		insertRecords = append(insertRecords, record)
	}

	// save all records
	for _, record := range insertRecords {
		if record != nil {
			err := app.Dao().SaveRecord(record)
			if err == nil {
				savedRecords = append(savedRecords, record)
			} else {
				return nil, err
			}
		}
	}

	return savedRecords, nil
}

func FindGroupByCourseAndSemester(course string, semester string, app *pocketbase.PocketBase) (*model.SeminarGroup, error) {
	var group model.SeminarGroup
	err := app.Dao().DB().Select("*").From("groups").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).One(&group)
	if err != nil {
		return nil, err
	}
	return &group, nil
}

func GetAllCourses(app *pocketbase.PocketBase) []string {

	var courses []struct {
		CourseShortcut string `db:"course" json:"course"`
	}

	// get all rooms from event records in the events collection
	err := app.Dao().DB().Select("course").From("groups").All(&courses)
	if err != nil {
		slog.Error("Error while getting groups from database: ", "error", err)
		return []string{}
	}

	var courseArray []string

	for _, course := range courses {
		courseArray = append(courseArray, course.CourseShortcut)
	}

	return courseArray
}

func GetAllCoursesForSemester(app *pocketbase.PocketBase, semester string) []string {

	var courses []struct {
		CourseShortcut string `db:"course" json:"course"`
	}

	// get all courses for a specific semester
	err := app.Dao().DB().Select("course").From("groups").Where(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).All(&courses)
	if err != nil {
		slog.Error("Error while getting groups from database: ", "error", err)
		return []string{}
	}

	var courseArray []string

	for _, course := range courses {
		courseArray = append(courseArray, course.CourseShortcut)
	}

	return courseArray

}

func GetAllCoursesForSemesterWithEvents(app *pocketbase.PocketBase, semester string) ([]string, error) {

	var courses []struct {
		CourseShortcut string `db:"course" json:"course"`
	}

	// get all courses from events distinct for a specific semester
	err := app.Dao().DB().Select("course").From("events").Where(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).Distinct(true).All(&courses)
	if err != nil {
		slog.Error("Error while getting groups from database: ", "error", err)
		return nil, err
	}

	var courseArray []string

	for _, course := range courses {
		courseArray = append(courseArray, course.CourseShortcut)
	}

	return courseArray, nil
}
