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

import (
	ics "github.com/arran4/golang-ical"
	"htwkalender/ical/model"
	"htwkalender/ical/service/functions"
	"log/slog"
	"net/url"
	"strings"
	_ "time/tzdata"
)

// Generates user-agent specific description and adds it to the calendar event.
func generateUserAgentSpecificDescription(vEvent *ics.VEvent, event model.Event, userAgent string) {
	// Generate description and ALTREP (alternative representation) based on user agent.
	description, altrep := generateDescription(event, userAgent)

	if isThunderbird(userAgent) && altrep != "" {
		uri := &url.URL{
			Scheme: "data",
			Opaque: altrep,
		}

		vEvent.AddProperty(ics.ComponentPropertyDescription, description, ics.WithAlternativeRepresentation(uri))
	} else {
		// Default handling: Add plain DESCRIPTION property for other user agents.
		vEvent.AddProperty("DESCRIPTION", description)
	}

}

// Generates description based on the event details and user agent.
func generateDescription(event model.Event, userAgent string) (string, string) {
	plainDescription := buildPlainTextDescription(event)

	if isThunderbird(userAgent) {
		// Thunderbird-specific: Generate HTML and ALTREP format for Thunderbird users.
		htmlDescription := generateThunderbirdHTMLDescription(event)
		altrep := `text/html,` + url.PathEscape(htmlDescription)
		return plainDescription, altrep
	}

	// Google Calendar-specific handling.
	if isGoogleCalendar(userAgent) {
		plainDescription += generateGoogleCalendarDescription(event.Rooms)
	}

	// Default: Return plain text description without ALTREP for non-Thunderbird cases.
	return plainDescription, ""
}

// Builds the plain text description from the event details.
func buildPlainTextDescription(event model.Event) string {
	var description string

	if !functions.OnlyWhitespace(event.Prof) {
		description += "Profs: " + event.Prof + "\n"
	}
	if !functions.OnlyWhitespace(event.Course) {
		description += "Gruppen: " + event.Course + "\n"
	}
	if !functions.OnlyWhitespace(event.EventType) {
		description += "Typ: " + event.EventType + event.Compulsory + "\n"
	}
	if !functions.OnlyWhitespace(event.Notes) {
		description += "Notizen: " + event.Notes + "\n"
	}

	return description
}

// Helper function to generate HTML description for Thunderbird's ALTREP.
func generateThunderbirdHTMLDescription(event model.Event) string {
	var htmlDescription strings.Builder

	// HTML-encoded description similar to plain text.
	if !functions.OnlyWhitespace(event.Prof) {
		htmlDescription.WriteString("Profs: " + event.Prof + "<br>")
	}
	if !functions.OnlyWhitespace(event.Course) {
		htmlDescription.WriteString("Gruppen: " + event.Course + "<br>")
	}
	if !functions.OnlyWhitespace(event.EventType) {
		htmlDescription.WriteString("Typ: " + event.EventType + event.Compulsory + "<br>")
	}

	roomList := functions.SeperateRoomString(event.Rooms)
	htmlDescription.WriteString("Orte: <br>")

	for _, room := range roomList {
		mapRoomName := functions.MapRoom(room, true)
		_, bufferErr := htmlDescription.WriteString("<a href=\"https://map.htwk-leipzig.de/room/" + mapRoomName + "\">" + room + "</a><br>")

		if bufferErr != nil {
			slog.Error("Error while writing to buffer", "error", bufferErr)
			return ""
		}
	}
	return htmlDescription.String()
}

// Generates a room description with links for Google Calendar.
func generateGoogleCalendarDescription(rooms string) string {
	var description strings.Builder
	roomList := functions.SeperateRoomString(rooms)
	description.WriteString("Orte: \n ")

	for _, room := range roomList {
		mapRoomName := functions.MapRoom(room, true)
		description.WriteString("<a href=\"https://map.htwk-leipzig.de/room/" + mapRoomName + "\"> " + mapRoomName + " </a>\n")
	}

	return description.String()
}

// Checks if the user agent is Thunderbird.
func isThunderbird(userAgent string) bool {
	return strings.Contains(userAgent, "Thunderbird")
}

// Checks if the user agent is Google Calendar.
func isGoogleCalendar(userAgent string) bool {
	return strings.Contains(userAgent, "Google-Calendar-Importer")
}
