package sonarr

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func TestCalendarUsesV3APIAndKeepsKeyInHeader(t *testing.T) {
	var gotQuery string
	upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/api/v3/calendar" {
			t.Errorf("path = %q", r.URL.Path)
		}
		if got := r.Header.Get("X-Api-Key"); got != "secret" {
			t.Errorf("X-Api-Key = %q", got)
		}
		if r.URL.Query().Get("includeSeries") != "true" ||
			r.URL.Query().Get("includeEpisodeFile") != "true" {
			t.Errorf("missing include flags: %s", r.URL.RawQuery)
		}
		gotQuery = r.URL.RawQuery
		w.Header().Set("Content-Type", "application/json")
		_, _ = w.Write([]byte(`[{"id":7,"seriesId":2,"title":"Arrival","hasFile":true}]`))
	}))
	defer upstream.Close()

	client := New(upstream.URL, "secret", time.Second)
	episodes, err := client.Calendar(
		context.Background(),
		time.Date(2026, 7, 27, 0, 0, 0, 0, time.UTC),
		time.Date(2026, 7, 28, 0, 0, 0, 0, time.UTC),
	)
	if err != nil {
		t.Fatal(err)
	}
	if len(episodes) != 1 || episodes[0].ID != 7 || !episodes[0].HasFile {
		t.Fatalf("unexpected episodes: %+v", episodes)
	}
	if gotQuery == "" || rHasAPIKey(gotQuery) {
		t.Fatalf("API key leaked into query: %q", gotQuery)
	}
}

func TestAddUnmonitoredUsesDefaultsWithoutStartingSearch(t *testing.T) {
	upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		switch r.URL.Path {
		case "/api/v3/rootfolder":
			_, _ = w.Write([]byte(`[{"path":"/tv"}]`))
		case "/api/v3/qualityprofile":
			_, _ = w.Write([]byte(`[{"id":3}]`))
		case "/api/v3/series":
			var body map[string]any
			if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
				t.Fatal(err)
			}
			if body["monitored"] != false || body["seasonFolder"] != true ||
				body["rootFolderPath"] != "/tv" || body["qualityProfileId"] != float64(3) {
				t.Errorf("unexpected add body: %#v", body)
			}
			seasons := body["seasons"].([]any)
			if seasons[0].(map[string]any)["monitored"] != false {
				t.Errorf("season remained monitored: %#v", body)
			}
			options := body["addOptions"].(map[string]any)
			if options["searchForMissingEpisodes"] != false {
				t.Errorf("episode search was enabled: %#v", body)
			}
			_, _ = w.Write([]byte(`{"id":8,"tvdbId":44,"title":"Severance"}`))
		default:
			t.Fatalf("unexpected path %s", r.URL.Path)
		}
	}))
	defer upstream.Close()

	added, err := New(upstream.URL, "secret", time.Second).AddUnmonitored(
		context.Background(), Series{
			TVDBID: 44, Title: "Severance", Monitored: true,
			Seasons: []Season{{SeasonNumber: 1, Monitored: true}},
		},
	)
	if err != nil {
		t.Fatal(err)
	}
	if added.ID != 8 {
		t.Fatalf("unexpected series: %+v", added)
	}
}

func rHasAPIKey(query string) bool {
	return strings.Contains(query, "secret")
}
