package azure

import (
	"context"
	"fmt"

	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	azurenetworkv1beta2 "github.com/upbound/provider-azure/apis/network/v1beta2"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

// FindReusablePrivateEndpointName tries to find a reusable Azure Private Endpoint
// matching the given service alias and subnet, so we do not need to create a new one.
func FindReusablePrivateEndpointName(ctx context.Context, cli client.Client, endpointServiceAlias, subnetID string) (string, error) {
	var endpointList azurenetworkv1beta2.PrivateEndpointList
	if err := cli.List(ctx, &endpointList); err != nil {
		return "", fmt.Errorf("failed to list private endpoints: %w", err)
	}
	for i := range endpointList.Items {
		ep := &endpointList.Items[i]
		if isPrivateEndpointReusable(ep, endpointServiceAlias, subnetID) {
			return ep.Name, nil
		}
	}
	return "", nil
}

func isPrivateEndpointReusable(ep *azurenetworkv1beta2.PrivateEndpoint, endpointServiceAlias, subnetID string) bool {
	psc := ep.Spec.ForProvider.PrivateServiceConnection
	if psc == nil {
		return false
	}
	// Match by alias (before Azure resolves it) or by resource ID (after Azure resolves alias to ID).
	aliasMatch := psc.PrivateConnectionResourceAlias != nil && *psc.PrivateConnectionResourceAlias == endpointServiceAlias
	idMatch := psc.PrivateConnectionResourceID != nil && *psc.PrivateConnectionResourceID == endpointServiceAlias
	if !aliasMatch && !idMatch {
		return false
	}
	if ep.Spec.ForProvider.SubnetID == nil || *ep.Spec.ForProvider.SubnetID != subnetID {
		return false
	}
	condition := ep.Status.GetCondition(xpv1.TypeReady)
	if condition.Reason == xpv1.ReasonDeleting {
		return false
	}
	return true
}

// ExtractPrivateIP extracts the private IP address from an Azure Private Endpoint status.
// It checks CustomDNSConfigs first, then falls back to PrivateServiceConnection.
func ExtractPrivateIP(ep *azurenetworkv1beta2.PrivateEndpoint) string {
	for _, dns := range ep.Status.AtProvider.CustomDNSConfigs {
		for _, ip := range dns.IPAddresses {
			if ip != nil && *ip != "" {
				return *ip
			}
		}
	}
	if psc := ep.Status.AtProvider.PrivateServiceConnection; psc != nil {
		if psc.PrivateIPAddress != nil && *psc.PrivateIPAddress != "" {
			return *psc.PrivateIPAddress
		}
	}
	return ""
}
