package approvalapp

import (
	"context"
	"fmt"
	"net/url"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/store/app"
	"github.com/tidbcloud/AgentTeam/internal/workflow/orchestrator"
)

// WriteApproval projects a request_approval Run effect through the Approval
// App transport. It intentionally writes no approval_instances row: the Run
// effect and orchestrator.DecisionSink remain the sole authority.
func (projector *Projector) WriteApproval(ctx context.Context, request orchestrator.ApprovalRequest) (orchestrator.ApprovalReceipt, error) {
	if projector == nil || projector.notifications == nil || projector.provisioner == nil || projector.now == nil {
		return orchestrator.ApprovalReceipt{}, fmt.Errorf("approval App Workflow Run projector is not configured")
	}
	request = request.Normalize()
	if err := request.Validate(); err != nil {
		return orchestrator.ApprovalReceipt{}, err
	}
	now := projector.now().UTC()
	if _, err := projector.provisioner.EnsureWorkspace(ctx, request.WorkspaceID, now); err != nil {
		return orchestrator.ApprovalReceipt{}, err
	}
	currentProcessorName, err := projector.provisioner.MemberDisplayName(
		ctx, request.WorkspaceID, request.AssigneeMemberID,
	)
	if err != nil {
		return orchestrator.ApprovalReceipt{}, err
	}
	content, err := pendingApprovalCardContent(request, currentProcessorName)
	if err != nil {
		return orchestrator.ApprovalReceipt{}, err
	}
	created, err := projector.notifications.CreateAppNotificationForBuiltin(ctx, IdentityID, request.WorkspaceID, app.AppNotificationCommand{
		ClientNotificationID: workflowRunApprovalClientNotificationID(request.RunID, request.EffectID),
		Target: app.AppNotificationTarget{
			Kind: app.AppNotificationTargetHumanDM, MemberID: request.AssigneeMemberID,
		},
		Content: content,
		BusinessObject: app.AppNotificationBusinessObject{
			Namespace: BusinessNamespace, Type: BusinessTypeWorkflowRunApproval,
			ID: request.EffectID, Version: 1,
			URL: "/workflow/runs/" + url.PathEscape(request.RunID),
		},
		RecipientBasis: app.AppNotificationRecipientBasis{
			Kind: RecipientBasisWorkflowRunAssignee, Ref: request.EffectID,
		},
		CausedByActor: app.AppNotificationActorRef{
			Type: "human", ID: request.CausedByMemberID,
		},
		CorrelationID: request.RunID,
	})
	if err != nil {
		return orchestrator.ApprovalReceipt{}, err
	}
	if strings.TrimSpace(created.NotificationID) == "" || strings.TrimSpace(created.MessageID) == "" || created.NotificationRevision <= 0 {
		return orchestrator.ApprovalReceipt{}, fmt.Errorf("approval App Workflow Run notification writer returned an incomplete receipt")
	}
	return orchestrator.ApprovalReceipt{
		NotificationID: created.NotificationID, MessageID: created.MessageID,
		NotificationRevision: created.NotificationRevision,
		IdempotentReplay:     created.AlreadyCreated,
	}, nil
}

var _ orchestrator.ApprovalWriter = (*Projector)(nil)
