package mailimp

import (
	"errors"
	"testing"

	"github.com/tech/sendico/pkg/merrors"
)

func TestNewMessageBuilder_CreatesValidBuilder(t *testing.T) {
	builder := NewMessageBuilder()
	if builder == nil {
		t.Fatal("Expected non-nil builder")
	}
	if builder.message == nil {
		t.Fatal("Expected builder to have initialized message")
	}
}

func TestMessageBuilder_BuildWithoutRecipient_ReturnsError(t *testing.T) {
	builder := NewMessageBuilder()
	_, err := builder.Build()

	if err == nil {
		t.Fatal("Expected error when building without recipient")
	}

	if !errors.Is(err, merrors.ErrInvalidArg) {
		t.Errorf("Expected InvalidArgument error, got: %v", err)
	}
}

func TestMessageBuilder_BuildWithRecipient_Success(t *testing.T) {
	builder := NewMessageBuilder()
	msg, err := builder.
		AddRecipient("John Doe", "john@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}
	if msg == nil {
		t.Fatal("Expected non-nil message")
	}
}

func TestMessageBuilder_SetAccountID_SetsCorrectValue(t *testing.T) {
	builder := NewMessageBuilder()
	accountID := "507f1f77bcf86cd799439011"

	msg, err := builder.
		SetAccountID(accountID).
		AddRecipient("Test User", "test@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if msg.AccountID() != accountID {
		t.Errorf("Expected AccountID %s, got %s", accountID, msg.AccountID())
	}
}

func TestMessageBuilder_SetTemplateID_SetsCorrectValue(t *testing.T) {
	builder := NewMessageBuilder()
	templateID := "welcome"

	msg, err := builder.
		SetTemplateID(templateID).
		AddRecipient("Test User", "test@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if msg.TemplateID() != templateID {
		t.Errorf("Expected TemplateID %s, got %s", templateID, msg.TemplateID())
	}
}

func TestMessageBuilder_SetLocale_SetsCorrectValue(t *testing.T) {
	builder := NewMessageBuilder()
	locale := "en-US"

	msg, err := builder.
		SetLocale(locale).
		AddRecipient("Test User", "test@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if msg.Locale() != locale {
		t.Errorf("Expected Locale %s, got %s", locale, msg.Locale())
	}
}

func TestMessageBuilder_AddRecipient_AddsToRecipientsList(t *testing.T) {
	builder := NewMessageBuilder()

	msg, err := builder.
		AddRecipient("User One", "user1@example.com").
		AddRecipient("User Two", "user2@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	recipients := msg.Recipients()
	if len(recipients) != 2 {
		t.Fatalf("Expected 2 recipients, got %d", len(recipients))
	}

	if recipients[0] != "user1@example.com" {
		t.Errorf("Expected first recipient to be user1@example.com, got %s", recipients[0])
	}
	if recipients[1] != "user2@example.com" {
		t.Errorf("Expected second recipient to be user2@example.com, got %s", recipients[1])
	}
}

func TestMessageBuilder_AddData_AccumulatesParameters(t *testing.T) {
	builder := NewMessageBuilder()

	msg, err := builder.
		AddData("key1", "value1").
		AddData("key2", "value2").
		AddRecipient("Test User", "test@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	params := msg.Parameters()
	if len(params) != 2 {
		t.Fatalf("Expected 2 parameters, got %d", len(params))
	}

	if params["key1"] != "value1" {
		t.Errorf("Expected key1=value1, got %v", params["key1"])
	}
	if params["key2"] != "value2" {
		t.Errorf("Expected key2=value2, got %v", params["key2"])
	}
}

func TestMessageBuilder_AddButton_StoresButtonLink(t *testing.T) {
	builder := NewMessageBuilder()
	buttonLink := "https://example.com/verify"

	msg, err := builder.
		AddButton(buttonLink).
		AddRecipient("Test User", "test@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	// Button link is internal, but we can verify the message was built successfully
	if msg == nil {
		t.Fatal("Expected non-nil message with button")
	}
}

func TestMessageBuilder_ChainedMethods_SetsAllFields(t *testing.T) {
	builder := NewMessageBuilder()

	msg, err := builder.
		SetAccountID("507f1f77bcf86cd799439011").
		SetTemplateID("welcome").
		SetLocale("en-US").
		AddButton("https://example.com/verify").
		AddRecipient("John Doe", "john@example.com").
		AddData("name", "John").
		AddData("age", "30").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	if msg.AccountID() != "507f1f77bcf86cd799439011" {
		t.Errorf("AccountID not set correctly")
	}
	if msg.TemplateID() != "welcome" {
		t.Errorf("TemplateID not set correctly")
	}
	if msg.Locale() != "en-US" {
		t.Errorf("Locale not set correctly")
	}
	if len(msg.Recipients()) != 1 {
		t.Errorf("Recipients not set correctly")
	}
	if len(msg.Parameters()) != 2 {
		t.Errorf("Parameters not set correctly")
	}
}

func TestMessageBuilder_MultipleBuilds_IndependentMessages(t *testing.T) {
	builder1 := NewMessageBuilder()
	builder2 := NewMessageBuilder()

	msg1, err1 := builder1.
		SetTemplateID("template1").
		AddRecipient("User 1", "user1@example.com").
		Build()

	msg2, err2 := builder2.
		SetTemplateID("template2").
		AddRecipient("User 2", "user2@example.com").
		Build()

	if err1 != nil || err2 != nil {
		t.Fatalf("Unexpected errors: %v, %v", err1, err2)
	}

	if msg1.TemplateID() == msg2.TemplateID() {
		t.Error("Messages should be independent with different template IDs")
	}

	if msg1.Recipients()[0] == msg2.Recipients()[0] {
		t.Error("Messages should be independent with different recipients")
	}
}

func TestMessageBuilder_EmptyValues_AreAllowed(t *testing.T) {
	builder := NewMessageBuilder()

	msg, err := builder.
		SetAccountID("").
		SetTemplateID("").
		SetLocale("").
		AddButton("").
		AddRecipient("", "user@example.com").
		Build()

	if err != nil {
		t.Fatalf("Unexpected error: %v", err)
	}

	// Empty values should be allowed - business logic validation happens elsewhere
	if msg == nil {
		t.Fatal("Expected message to be built even with empty values")
	}
}
