package socketclients

import (
	"strings"

	"lms.de/backend/modules/cache"
	"lms.de/backend/modules/structs"
)

func BroadcastMessage(organizationId string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.OrganizationId == organizationId {
			client.SendMessage(sendSocketMessage)
		}
	}
}

func BroadcastMessageToTopic(organizationId string, topic string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if hasClientSubscribedToTopic(topic, client.SubscribedTopic) {
			client.SendMessage(sendSocketMessage)
		}
	}
}

func BroadcastMessageExceptBrowserTabSession(organizationId string, browserTabSession string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.OrganizationId == organizationId && client.BrowserTabSession != browserTabSession {
			client.SendMessage(sendSocketMessage)
		}
	}
}

func BroadcastMessageToTopicExceptBrowserTabSession(organizationId string, topic string, browserTabSession string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.SubscribedTopic == topic && client.BrowserTabSession != browserTabSession && client.OrganizationId == organizationId {
			client.SendMessage(sendSocketMessage)
		}
	}
}

func BroadcastMessageToTopicStartsWithExceptBrowserTabSession(organizationId string, topic string, browserTabSession string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if strings.HasPrefix(client.SubscribedTopic, topic) && client.BrowserTabSession != browserTabSession && client.OrganizationId == organizationId {
			client.SendMessage(sendSocketMessage)
		}
	}
}

func BroadcastMessageToTopicsExceptBrowserTabSession(organizationId string, topics []string, browserTabSession string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.OrganizationId == organizationId && client.BrowserTabSession != browserTabSession {
			for _, topic := range topics {
				if client.SubscribedTopic == topic {
					client.SendMessage(sendSocketMessage)
				}
			}
		}
	}
}

func BroadcastMessageToTopics(organizationId string, topics []string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.OrganizationId == organizationId {
			for _, topic := range topics {
				if client.SubscribedTopic == topic {
					client.SendMessage(sendSocketMessage)
				}
			}
		}
	}
}

func hasClientSubscribedToTopic(topic string, clientTopic string) bool {
	return clientTopic == topic /* || strings.HasPrefix(clientTopic, topic) */
}

// Used to determine if a user is connected regardless of the session used
func IsUserConnected(userId string) bool {
	for _, socketClient := range cache.GetSocketClients() {
		if socketClient.UserId == userId {
			return true
		}
	}

	return false
}

func SendMessageToUserWithTopicExceptBrowserTabSession(userId string, topic string, browserTabSession string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.UserId == userId && client.SubscribedTopic == topic && client.BrowserTabSession != browserTabSession {
			client.SendMessage(sendSocketMessage)
		}
	}
}

func SendMessageToUserWithTopic(userId string, topic string, sendSocketMessage structs.SendSocketMessage) {
	for _, client := range cache.GetSocketClients() {
		if client.UserId == userId && client.SubscribedTopic == topic {
			client.SendMessage(sendSocketMessage)
		}
	}
}
