package repository_test

import (
	"context"
	"testing"

	"gateway/internal/model/notification"
	domentity "gateway/internal/model/notification/domain/entity"
	"gateway/internal/model/notification/domain/enum"
	domrepo "gateway/internal/model/notification/domain/repository"
	"gateway/internal/model/notification/repository"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

const memTestTenant = "tenant-mem"

func TestMemoryNotificationRepository_InsertDuplicateIdempotency(t *testing.T) {
	repo := repository.NewMemoryNotificationRepository()
	ctx := context.Background()

	doc := &domentity.Notification{
		TenantID:       memTestTenant,
		Kind:           enum.NotifyVerifyEmail,
		IdempotencyKey: "dup-1",
		Channel:        enum.ChannelEmail,
	}
	require.NoError(t, repo.Insert(ctx, doc))
	require.NotEmpty(t, doc.ID.Hex())

	err := repo.Insert(ctx, &domentity.Notification{
		TenantID:       memTestTenant,
		Kind:           enum.NotifyVerifyEmail,
		IdempotencyKey: "dup-1",
		Channel:        enum.ChannelEmail,
	})
	require.ErrorIs(t, err, notification.ErrDuplicateIdempotency)
}

func TestMemoryNotificationRepository_FindByIdempotency(t *testing.T) {
	repo := repository.NewMemoryNotificationRepository()
	ctx := context.Background()

	doc := &domentity.Notification{
		TenantID:       memTestTenant,
		Kind:           enum.NotifyVerifyPhone,
		IdempotencyKey: "find-1",
	}
	require.NoError(t, repo.Insert(ctx, doc))

	found, err := repo.FindByIdempotency(ctx, memTestTenant, enum.NotifyVerifyPhone, "find-1")
	require.NoError(t, err)
	assert.Equal(t, doc.ID, found.ID)

	_, err = repo.FindByIdempotency(ctx, memTestTenant, enum.NotifyVerifyPhone, "missing")
	require.ErrorIs(t, err, notification.ErrNotFound)
}

func TestMemoryNotificationRepository_UpdateDeliveryBody(t *testing.T) {
	repo := repository.NewMemoryNotificationRepository()
	ctx := context.Background()

	doc := &domentity.Notification{
		TenantID:       memTestTenant,
		Kind:           enum.NotifyStepUpEmail,
		IdempotencyKey: "body-1",
	}
	require.NoError(t, repo.Insert(ctx, doc))

	require.NoError(t, repo.UpdateDelivery(ctx, memTestTenant, doc.ID.Hex(), &domrepo.NotificationDeliveryUpdate{
		Status: enum.NotifyStatusSent,
		Body:   "",
	}))

	stored, err := repo.FindByID(ctx, memTestTenant, doc.ID.Hex())
	require.NoError(t, err)
	assert.Empty(t, stored.Body)
}
