package notifications

import (
	"context"
	"testing"
	"time"

	"bookra/apps/backend/internal/config"
	"bookra/apps/backend/internal/db"
	"bookra/apps/backend/internal/domain"
)

func TestDispatchDueProcessesPendingEmailReminders(t *testing.T) {
	repo := db.NewMemoryRepository()
	startsAt := time.Now().UTC().Add(26 * time.Hour)
	created, err := repo.CreateBooking(context.Background(), db.CreateBookingParams{
		TenantID:      "5d6b3551-0a3e-4b86-bdf0-e9df20a47148",
		BookingMode:   "appointment",
		CustomerName:  "Reminder Customer",
		CustomerEmail: "reminder@example.com",
		StartsAt:      startsAt,
		EndsAt:        startsAt.Add(time.Hour),
		Status:        "confirmed",
		Reference:     "BK-TEST-REMINDER",
	})
	if err != nil {
		t.Fatalf("create booking: %v", err)
	}
	if err := repo.CreateReminderJob(context.Background(), db.ReminderJobParams{
		TenantID:     "5d6b3551-0a3e-4b86-bdf0-e9df20a47148",
		BookingID:    created.ID,
		Channel:      "email",
		ScheduledFor: time.Now().UTC().Add(-time.Minute),
	}); err != nil {
		t.Fatalf("create reminder job: %v", err)
	}

	service := NewService(config.Config{
		Environment: "development",
		EmailFrom:   "noreply@bookra.dev",
	}, repo)

	response, err := service.DispatchDue(context.Background(), 10)
	if err != nil {
		t.Fatalf("dispatch due: %v", err)
	}
	if response.ProcessedCount != 1 {
		t.Fatalf("expected processed count 1, got %d", response.ProcessedCount)
	}
	if response.SentCount != 1 {
		t.Fatalf("expected sent count 1, got %d", response.SentCount)
	}
	if response.FailedCount != 0 {
		t.Fatalf("expected failed count 0, got %d", response.FailedCount)
	}

	pending, err := repo.ListDueReminderJobs(context.Background(), time.Now().UTC().Add(time.Hour), 10)
	if err != nil {
		t.Fatalf("list due reminder jobs: %v", err)
	}
	if len(pending) != 0 {
		t.Fatalf("expected no pending jobs after dispatch, got %d", len(pending))
	}
}

func TestDispatchDueFailsUnknownChannel(t *testing.T) {
	repo := db.NewMemoryRepository()
	if err := repo.CreateReminderJob(context.Background(), db.ReminderJobParams{
		TenantID:     "5d6b3551-0a3e-4b86-bdf0-e9df20a47148",
		BookingID:    "booking-unknown-channel",
		Channel:      "push",
		ScheduledFor: time.Now().UTC().Add(-time.Minute),
	}); err != nil {
		t.Fatalf("create reminder job: %v", err)
	}

	service := NewService(config.Config{Environment: "development"}, repo)
	response, err := service.DispatchDue(context.Background(), 10)
	if err != nil {
		t.Fatalf("dispatch due: %v", err)
	}
	if response.ProcessedCount != 1 || response.FailedCount != 1 {
		t.Fatalf("expected one failed job, got %+v", response)
	}
}

func TestDispatchRequestContractShape(t *testing.T) {
	request := domain.DispatchReminderJobsRequest{Limit: 20}
	if request.Limit != 20 {
		t.Fatalf("expected limit 20, got %d", request.Limit)
	}
}
