package email

import (
	"bytes"
	"context"
	"strings"
	"testing"

	"github.com/nexuscrm/kernel/pkg/ports"
	"github.com/nexuscrm/kernel/pkg/logging"
	"github.com/rs/zerolog"
)

func TestNoopSenderSendReturnsAcceptedRecipientResults(t *testing.T) {
	sender := NewNoopSender(logging.New(context.Background()))
	msg := &ports.EmailMessage{
		To:      []string{"to@example.com"},
		Cc:      []string{"cc@example.com"},
		Bcc:     []string{"bcc@example.com"},
		Subject: "Hello",
		Body:    "Body",
	}

	result, err := sender.Send(context.Background(), msg)
	if err != nil {
		t.Fatalf("Send: %v", err)
	}
	if result == nil {
		t.Fatal("Send result is nil")
	}
	if result.SentCount != 3 {
		t.Fatalf("SentCount = %d; want 3", result.SentCount)
	}
	if result.MessageID != "" {
		t.Fatalf("MessageID = %q; want empty", result.MessageID)
	}
	want := []ports.EmailRecipientResult{
		{Address: "to@example.com", Role: "to", Status: "accepted"},
		{Address: "cc@example.com", Role: "cc", Status: "accepted"},
		{Address: "bcc@example.com", Role: "bcc", Status: "accepted"},
	}
	if len(result.RecipientResults) != len(want) {
		t.Fatalf("RecipientResults len = %d; want %d", len(result.RecipientResults), len(want))
	}
	for i := range want {
		if result.RecipientResults[i] != want[i] {
			t.Fatalf("RecipientResults[%d] = %#v; want %#v", i, result.RecipientResults[i], want[i])
		}
	}
}

func TestNoopSenderLogOmitsMessageContentAndRecipients(t *testing.T) {
	var logBuf bytes.Buffer
	sender := NewNoopSender(newNoopSenderTestLogger(&logBuf))
	msg := &ports.EmailMessage{
		To:      []string{"sensitive-recipient@example.com"},
		Cc:      []string{"sensitive-reviewer@example.com"},
		Bcc:     []string{"hidden-recipient@example.com"},
		Subject: "Private Sensitive Plan",
		Body:    "Sensitive plain body",
		HTML:    "<p>Sensitive html body</p>",
	}

	if _, err := sender.Send(context.Background(), msg); err != nil {
		t.Fatalf("Send: %v", err)
	}

	logged := logBuf.String()
	for _, forbidden := range []string{
		"sensitive-recipient@example.com",
		"sensitive-reviewer@example.com",
		"hidden-recipient@example.com",
		"Private Sensitive Plan",
		"Sensitive plain body",
		"Sensitive html body",
	} {
		if strings.Contains(logged, forbidden) {
			t.Fatalf("NoopSender log leaked %q in %q", forbidden, logged)
		}
	}
	for _, want := range []string{"[NOOP EMAIL]", "ToCount=1", "CcCount=1", "BccCount=1", "RecipientCount=3", "Status=accepted"} {
		if !strings.Contains(logged, want) {
			t.Fatalf("NoopSender log = %q; want non-sensitive marker %q", logged, want)
		}
	}
}

func newNoopSenderTestLogger(buf *bytes.Buffer) *logging.Logger {
	tctx := zerolog.New(buf).WithContext(context.Background())
	return logging.New(tctx)
}
