package store

import (
	"context"
	"path/filepath"
	"testing"
	"time"

	"github.com/oklog/ulid/v2"
)

func TestNotificationChannelCRUD(t *testing.T) {
	t.Parallel()
	dir := t.TempDir()
	st, err := Open(context.Background(), filepath.Join(dir, "rm.db"))
	if err != nil {
		t.Fatalf("open: %v", err)
	}
	defer st.Close()
	ctx := context.Background()

	ch := NotificationChannel{
		ID: ulid.Make().String(), Kind: "webhook", Name: "team-slack",
		Enabled: true, Config: []byte("encrypted-blob"),
		CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(),
	}
	if err := st.CreateNotificationChannel(ctx, ch); err != nil {
		t.Fatalf("create: %v", err)
	}

	got, err := st.GetNotificationChannel(ctx, ch.ID)
	if err != nil {
		t.Fatalf("get: %v", err)
	}
	if got.Name != ch.Name || got.Kind != "webhook" || string(got.Config) != "encrypted-blob" {
		t.Fatalf("got %+v", got)
	}

	got.Name = "team-slack-renamed"
	got.Enabled = false
	got.UpdatedAt = time.Now().UTC()
	if err := st.UpdateNotificationChannel(ctx, *got); err != nil {
		t.Fatalf("update: %v", err)
	}
	got2, _ := st.GetNotificationChannel(ctx, ch.ID)
	if got2.Name != "team-slack-renamed" || got2.Enabled {
		t.Fatalf("update not applied: %+v", got2)
	}

	all, _ := st.ListEnabledNotificationChannels(ctx)
	if len(all) != 0 {
		t.Errorf("disabled channel returned by ListEnabled: %d", len(all))
	}

	if err := st.DeleteNotificationChannel(ctx, ch.ID); err != nil {
		t.Fatalf("delete: %v", err)
	}
	if _, err := st.GetNotificationChannel(ctx, ch.ID); err == nil {
		t.Errorf("expected ErrNotFound after delete")
	}
}

func TestAppendNotificationLog(t *testing.T) {
	t.Parallel()
	dir := t.TempDir()
	st, _ := Open(context.Background(), filepath.Join(dir, "rm.db"))
	defer st.Close()
	ctx := context.Background()

	chID := ulid.Make().String()
	if err := st.CreateNotificationChannel(ctx, NotificationChannel{
		ID: chID, Kind: "ntfy", Name: "n", Enabled: true,
		Config:    []byte{1, 2, 3},
		CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(),
	}); err != nil {
		t.Fatalf("create channel: %v", err)
	}

	code := 200
	lat := 287
	if err := st.AppendNotificationLog(ctx, NotificationLogEntry{
		ID: ulid.Make().String(), ChannelID: chID, Event: "alert.test",
		OK: true, StatusCode: &code, LatencyMS: &lat,
		FiredAt: time.Now().UTC(),
	}); err != nil {
		t.Fatalf("append: %v", err)
	}

	// LastFiredAt projection: the channel's last_fired_at is updated
	// either by the append helper or by the callers; if you choose the
	// helper does the bump, assert it.
	got, _ := st.GetNotificationChannel(ctx, chID)
	if got.LastFiredAt == nil {
		t.Errorf("last_fired_at should bump on AppendNotificationLog success")
	}
}
