package webhooks

import (
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/store/app/runtime"
)

type ServiceEventConnectionStatus string

const (
	ServiceEventConnectionReady                  ServiceEventConnectionStatus = "ready"
	ServiceEventConnectionWorkspaceNotConfigured ServiceEventConnectionStatus = "workspace_not_configured"
	ServiceEventConnectionResourceNotAccessible  ServiceEventConnectionStatus = "resource_not_accessible"
)

func ResolveGitHubServiceEventConnectionFromConnections(connections []runtime.ConnectionView, repositoryFullName string, expectedConnectionRef string) (string, ServiceEventConnectionStatus) {
	repositoryOwner := serviceEventRepositoryOwner(repositoryFullName)
	expected := strings.TrimSpace(expectedConnectionRef)
	if expected != "" {
		for _, connection := range connections {
			if strings.TrimSpace(connection.ExternalSubjectRef) != expected {
				continue
			}
			if repositoryOwner == "" || gitHubServiceEventConnectionMatchesRepositoryOwner(connection, repositoryOwner) {
				return strings.TrimSpace(connection.ExternalSubjectRef), ServiceEventConnectionReady
			}
			if len(connections) == 1 && !gitHubServiceEventConnectionHasKnownOwner(connection) {
				return strings.TrimSpace(connection.ExternalSubjectRef), ServiceEventConnectionReady
			}
			return "", ServiceEventConnectionResourceNotAccessible
		}
		return "", ServiceEventConnectionWorkspaceNotConfigured
	}

	for _, connection := range connections {
		if repositoryOwner != "" && gitHubServiceEventConnectionMatchesRepositoryOwner(connection, repositoryOwner) {
			return strings.TrimSpace(connection.ExternalSubjectRef), ServiceEventConnectionReady
		}
	}
	if len(connections) == 1 && !gitHubServiceEventConnectionHasKnownOwner(connections[0]) {
		return strings.TrimSpace(connections[0].ExternalSubjectRef), ServiceEventConnectionReady
	}
	return "", ServiceEventConnectionResourceNotAccessible
}

func ResolveGiteaServiceEventConnectionFromConnections(connections []runtime.ConnectionView, repositoryFullName string, expectedConnectionRef string) (string, ServiceEventConnectionStatus) {
	repository := normalizeServiceEventRepository(repositoryFullName)
	repositoryOwner := serviceEventRepositoryOwner(repository)
	expected := strings.ToLower(strings.TrimSpace(expectedConnectionRef))
	if expected != "" {
		for _, connection := range connections {
			connectionRef := strings.ToLower(strings.TrimSpace(connection.ExternalSubjectRef))
			if connectionRef != expected {
				continue
			}
			if connectionRef == repository || connectionRef == repositoryOwner {
				return strings.TrimSpace(connection.ExternalSubjectRef), ServiceEventConnectionReady
			}
			return "", ServiceEventConnectionResourceNotAccessible
		}
		return "", ServiceEventConnectionWorkspaceNotConfigured
	}

	for _, connection := range connections {
		connectionRef := strings.ToLower(strings.TrimSpace(connection.ExternalSubjectRef))
		if connectionRef == repository {
			return strings.TrimSpace(connection.ExternalSubjectRef), ServiceEventConnectionReady
		}
	}
	for _, connection := range connections {
		connectionRef := strings.ToLower(strings.TrimSpace(connection.ExternalSubjectRef))
		if repositoryOwner != "" && connectionRef == repositoryOwner {
			return strings.TrimSpace(connection.ExternalSubjectRef), ServiceEventConnectionReady
		}
	}
	return "", ServiceEventConnectionResourceNotAccessible
}

func gitHubServiceEventConnectionMatchesRepositoryOwner(connection runtime.ConnectionView, repositoryOwner string) bool {
	if strings.TrimSpace(repositoryOwner) == "" {
		return false
	}
	ownerLabel := gitHubServiceEventConnectionOwnerLabel(connection)
	return ownerLabel != "" && strings.EqualFold(ownerLabel, repositoryOwner)
}

func gitHubServiceEventConnectionHasKnownOwner(connection runtime.ConnectionView) bool {
	return gitHubServiceEventConnectionOwnerLabel(connection) != ""
}

func gitHubServiceEventConnectionOwnerLabel(connection runtime.ConnectionView) string {
	label := strings.TrimSpace(connection.DisplayLabel)
	if label == "" {
		return ""
	}
	if strings.EqualFold(label, strings.TrimSpace(connection.ExternalSubjectRef)) {
		return ""
	}
	return strings.ToLower(label)
}

func normalizeServiceEventRepository(value string) string {
	return strings.ToLower(strings.TrimSpace(value))
}

func serviceEventRepositoryOwner(repositoryFullName string) string {
	trimmed := normalizeServiceEventRepository(repositoryFullName)
	separator := strings.Index(trimmed, "/")
	if separator <= 0 {
		return ""
	}
	return trimmed[:separator]
}
