package internal

import (
	"net/http"
	"net/http/httptest"
	"os"
	"sync/atomic"
	"testing"
	"time"
)

func TestRefreshLibraryDebouncesBurst(t *testing.T) {
	defer safeClearTimer()

	var calls atomic.Int32
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		calls.Add(1)
		if r.Method != http.MethodPost {
			t.Fatalf("expected POST, got %s", r.Method)
		}
		if r.URL.Path != "/Library/Refresh" {
			t.Fatalf("unexpected path %q", r.URL.Path)
		}
		if token := r.Header.Get("X-Emby-Token"); token != "admin-token" {
			t.Fatalf("expected API token header, got %q", token)
		}
		w.WriteHeader(http.StatusNoContent)
	}))
	defer srv.Close()

	t.Setenv("JELLYFIN_URL", srv.URL)
	t.Setenv("JELLYFIN_API_KEY", "admin-token")

	j := &Jellyfin{Client: srv.Client()}
	j.RefreshLibrary("fallback-user-token")
	j.RefreshLibrary("fallback-user-token")
	j.RefreshLibrary("fallback-user-token")

	time.Sleep(2500 * time.Millisecond)
	if got := calls.Load(); got != 1 {
		t.Fatalf("expected one debounced refresh request, got %d", got)
	}
}

func TestRefreshLibrarySkipsWithoutToken(t *testing.T) {
	defer safeClearTimer()

	var calls atomic.Int32
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		calls.Add(1)
		w.WriteHeader(http.StatusNoContent)
	}))
	defer srv.Close()

	t.Setenv("JELLYFIN_URL", srv.URL)
	t.Setenv("JELLYFIN_API_KEY", "")

	j := &Jellyfin{Client: srv.Client()}
	j.RefreshLibrary("")

	time.Sleep(2500 * time.Millisecond)
	if got := calls.Load(); got != 0 {
		t.Fatalf("expected zero refresh requests without token, got %d", got)
	}
}

func TestRefreshLibrarySkipsWithoutURL(t *testing.T) {
	defer safeClearTimer()

	orig := os.Getenv("JELLYFIN_URL")
	if err := os.Unsetenv("JELLYFIN_URL"); err != nil {
		t.Fatalf("unset env failed: %v", err)
	}
	t.Cleanup(func() {
		_ = os.Setenv("JELLYFIN_URL", orig)
	})
	t.Setenv("JELLYFIN_API_KEY", "admin-token")

	j := &Jellyfin{Client: &http.Client{Timeout: 200 * time.Millisecond}}
	j.RefreshLibrary("fallback-user-token")

	time.Sleep(2500 * time.Millisecond)
	if refreshTimer != nil {
		t.Fatalf("expected timer to self-clear after skip")
	}
}

func TestRefreshLibraryUsesFallbackClientAndHandlesServerError(t *testing.T) {
	defer safeClearTimer()

	var calls atomic.Int32
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		calls.Add(1)
		w.WriteHeader(http.StatusInternalServerError)
	}))
	defer srv.Close()

	t.Setenv("JELLYFIN_URL", srv.URL)
	t.Setenv("JELLYFIN_API_KEY", "admin-token")

	j := &Jellyfin{}
	j.RefreshLibrary("fallback-user-token")

	time.Sleep(2500 * time.Millisecond)
	if got := calls.Load(); got != 1 {
		t.Fatalf("expected one refresh request, got %d", got)
	}
}
