package notify

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"forge.secuaas.ovh/olivier/claude-failover/internal/config"
)

// TestTelegramNoop verifies that an unconfigured notifier is a safe no-op.
func TestTelegramNoop(t *testing.T) {
	n := &Notifier{}
	if err := n.Telegram("hello"); err != nil {
		t.Errorf("expected nil error for empty token, got %v", err)
	}
}

// TestEmailNoop verifies that an unconfigured notifier is a safe no-op.
func TestEmailNoop(t *testing.T) {
	n := &Notifier{}
	if err := n.Email("subject", "<p>body</p>"); err != nil {
		t.Errorf("expected nil error for empty API key, got %v", err)
	}
}

// TestNewFromConfig verifies that New reads credentials from env vars.
func TestNewFromConfig(t *testing.T) {
	t.Setenv("TEST_TG_TOKEN", "my-token")
	t.Setenv("TEST_TG_CHAT", "9999")
	t.Setenv("TEST_EMAIL", "ops@example.com")

	cfg := &config.Config{
		Notifications: config.NotificationsConfig{
			TelegramTokenEnv:  "TEST_TG_TOKEN",
			TelegramChatIDEnv: "TEST_TG_CHAT",
			NotifyEmailEnv:    "TEST_EMAIL",
		},
	}
	n := New(cfg)
	if n.telegramToken != "my-token" {
		t.Errorf("expected token my-token, got %q", n.telegramToken)
	}
	if n.telegramChatID != "9999" {
		t.Errorf("expected chatID 9999, got %q", n.telegramChatID)
	}
	if n.notifyEmail != "ops@example.com" {
		t.Errorf("expected email ops@example.com, got %q", n.notifyEmail)
	}
}

// TestTelegramHTTP verifies the actual HTTP body sent to Telegram.
func TestTelegramHTTP(t *testing.T) {
	var gotBody map[string]string
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		json.NewDecoder(r.Body).Decode(&gotBody)
		w.WriteHeader(200)
		w.Write([]byte(`{"ok":true}`))
	}))
	defer srv.Close()

	n := &Notifier{
		telegramToken:   "tok",
		telegramChatID:  "42",
		httpClient:      srv.Client(),
		telegramBaseURL: srv.URL,
	}
	if err := n.Telegram("test message"); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if gotBody["text"] != "test message" {
		t.Errorf("expected text 'test message', got %q", gotBody["text"])
	}
	if gotBody["chat_id"] != "42" {
		t.Errorf("expected chat_id 42, got %q", gotBody["chat_id"])
	}
}

// TestEmailHTTP verifies the HTTP body sent to Resend.
func TestEmailHTTP(t *testing.T) {
	var gotBody map[string]interface{}
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		json.NewDecoder(r.Body).Decode(&gotBody)
		if r.Header.Get("Authorization") != "Bearer test-key" {
			t.Errorf("unexpected Authorization header: %q", r.Header.Get("Authorization"))
		}
		w.WriteHeader(201)
		w.Write([]byte(`{"id":"msg-123"}`))
	}))
	defer srv.Close()

	n := &Notifier{
		resendAPIKey:  "test-key",
		notifyEmail:   "user@example.com",
		httpClient:    srv.Client(),
		resendBaseURL: srv.URL,
	}
	if err := n.Email("Alert", "<p>something happened</p>"); err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if gotBody["subject"] != "Alert" {
		t.Errorf("expected subject Alert, got %v", gotBody["subject"])
	}
}

// TestTelegramHTTPError propagates non-2xx status as error.
func TestTelegramHTTPError(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(429)
	}))
	defer srv.Close()

	n := &Notifier{
		telegramToken:   "tok",
		telegramChatID:  "1",
		httpClient:      srv.Client(),
		telegramBaseURL: srv.URL,
	}
	if err := n.Telegram("msg"); err == nil {
		t.Error("expected error on HTTP 429, got nil")
	}
}
