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

import (
	"github.com/pocketbase/pocketbase/models"
	"slices"
	"sort"
	"strings"
	"time"
)

type Events []Event

func (events Events) Contains(event Event) bool {
	return slices.Contains(events, event)
}

func (events Events) Sort() {
	// Sort events by start time
	sort.Slice(events, func(i, j int) bool {
		return time.Time(events[i].Start).Before(time.Time(events[j].Start))
	})
}

type AnonymizedEventDTO struct {
	Day   string   `db:"Day" json:"day"`
	Week  string   `db:"Week" json:"week"`
	Start JSONTime `db:"start" json:"start"`
	End   JSONTime `db:"end" json:"end"`
	Rooms string   `db:"Rooms" json:"rooms"`
	Free  bool     `json:"free"`
}

type Event struct {
	UUID       string   `db:"uuid" json:"uuid"`
	Day        string   `db:"Day" json:"day"`
	Week       string   `db:"Week" json:"week"`
	Start      JSONTime `db:"start" json:"start"`
	End        JSONTime `db:"end" json:"end"`
	Name       string   `db:"Name" json:"name"`
	EventType  string   `db:"EventType" json:"eventType"`
	Compulsory string   `db:"Compulsory" json:"compulsory"`
	Prof       string   `db:"Prof" json:"prof"`
	Rooms      string   `db:"Rooms" json:"rooms"`
	Notes      string   `db:"Notes" json:"notes"`
	BookedAt   string   `db:"BookedAt" json:"bookedAt"`
	Course     string   `db:"course" json:"course"`
	Semester   string   `db:"semester" json:"semester"`
	models.BaseModel
}

type EventType struct {
	EventType string `db:"EventType" json:"eventType"`
}

func (e *Event) Equals(event Event) bool {
	return e.Day == event.Day &&
		e.Week == event.Week &&
		e.Start == event.Start &&
		e.End == event.End &&
		e.Name == event.Name &&
		e.Course == event.Course &&
		e.Prof == event.Prof &&
		e.Rooms == event.Rooms &&
		e.EventType == event.EventType
}

func (e *Event) TableName() string {
	return "events"
}

// SetCourse func to set the course and returns the event
func (e *Event) SetCourse(course string) Event {
	e.Course = course
	return *e
}

// AnonymizeEvent Creates an AnonymizedEventDTO from an Event hiding all sensitive data
func (e *Event) AnonymizeEvent() AnonymizedEventDTO {
	return AnonymizedEventDTO{
		Day:   e.Day,
		Week:  e.Week,
		Start: e.Start,
		End:   e.End,
		Rooms: e.Rooms,
		Free:  strings.Contains(strings.ToLower(e.Name), "zur freien verfügung"),
	}
}

func (e *Event) GetName() string {
	return e.Name
}

func (e *Event) SetName(name string) {
	e.Name = name
}
