//go:build integration

package jobs_test

import (
	"context"
	"encoding/json"
	"testing"
	"time"

	"github.com/google/uuid"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/yan1h/agent-coding-workflow/internal/infra/clock"
	"github.com/yan1h/agent-coding-workflow/internal/infra/notify"
	"github.com/yan1h/agent-coding-workflow/internal/jobs"
)

func TestWebhookNotifier_EnqueuesForWhitelistedTopic(t *testing.T) {
	t.Parallel()
	repo, _ := setupRepo(t)
	ctx := context.Background()
	n := jobs.NewWebhookNotifier(repo, jobs.WebhookNotifierConfig{
		Enabled: true,
		Topics:  []string{"workspace.sync_failed"},
		Backoff: []time.Duration{30 * time.Second},
	}, clock.Real(), nil, nil)

	err := n.Send(ctx, notify.Message{
		ID: uuid.New(), UserID: uuid.New(), Topic: "workspace.sync_failed",
		Severity: notify.SeverityError, Title: "fail", Body: "x",
		CreatedAt: time.Now(),
	})
	require.NoError(t, err)
	got, err := repo.Lease(ctx, "test-lease")
	require.NoError(t, err)
	require.NotNil(t, got)
	assert.Equal(t, jobs.TypeWebhookDeliver, got.Type)

	var payload map[string]any
	require.NoError(t, json.Unmarshal(got.Payload, &payload))
	assert.Equal(t, "workspace.sync_failed", payload["topic"])
}

func TestWebhookNotifier_DropsNonWhitelistedTopic(t *testing.T) {
	t.Parallel()
	repo, _ := setupRepo(t)
	ctx := context.Background()
	n := jobs.NewWebhookNotifier(repo, jobs.WebhookNotifierConfig{
		Enabled: true,
		Topics:  []string{"workspace.sync_failed"},
		Backoff: []time.Duration{30 * time.Second},
	}, clock.Real(), nil, nil)

	err := n.Send(ctx, notify.Message{
		ID: uuid.New(), UserID: uuid.New(), Topic: "chat.message_failed",
		Severity: notify.SeverityError, CreatedAt: time.Now(),
	})
	require.NoError(t, err)
	got, _ := repo.Lease(ctx, "t")
	assert.Nil(t, got, "non-whitelisted topic must not enqueue")
}

func TestWebhookNotifier_DisabledShortCircuits(t *testing.T) {
	t.Parallel()
	repo, _ := setupRepo(t)
	ctx := context.Background()
	n := jobs.NewWebhookNotifier(repo, jobs.WebhookNotifierConfig{
		Enabled: false,
		Topics:  []string{"workspace.sync_failed"},
	}, clock.Real(), nil, nil)
	err := n.Send(ctx, notify.Message{
		ID: uuid.New(), UserID: uuid.New(), Topic: "workspace.sync_failed", CreatedAt: time.Now(),
	})
	require.NoError(t, err)
	got, _ := repo.Lease(ctx, "t")
	assert.Nil(t, got)
}

func TestWebhookNotifier_Name(t *testing.T) {
	n := jobs.NewWebhookNotifier(nil, jobs.WebhookNotifierConfig{}, clock.Real(), nil, nil)
	assert.Equal(t, notify.ChannelWebhook, n.Name())
}
