package api

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

	"github.com/go-chi/chi/v5"

	"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
)

func newLibraryAlbumsRouter(h *handlers) chi.Router {
	r := chi.NewRouter()
	r.Get("/api/library/albums", h.handleListLibraryAlbums)
	return r
}

func doListLibraryAlbums(h *handlers, user dbq.User, query string) *httptest.ResponseRecorder {
	url := "/api/library/albums"
	if query != "" {
		url += "?" + query
	}
	req := httptest.NewRequest(http.MethodGet, url, nil)
	req = withUser(req, user)
	w := httptest.NewRecorder()
	newLibraryAlbumsRouter(h).ServeHTTP(w, req)
	return w
}

func TestLibraryAlbums_AlphaSorted(t *testing.T) {
	h, pool := testHandlers(t)
	user := seedUser(t, pool, "alice", "pw", false)
	q := dbq.New(pool)
	artist, _ := q.UpsertArtist(context.Background(), dbq.UpsertArtistParams{
		Name: "ArtistA", SortName: "ArtistA",
	})
	_, _ = q.UpsertAlbum(context.Background(), dbq.UpsertAlbumParams{
		Title: "Zoo", SortTitle: "Zoo", ArtistID: artist.ID,
	})
	_, _ = q.UpsertAlbum(context.Background(), dbq.UpsertAlbumParams{
		Title: "Apple", SortTitle: "Apple", ArtistID: artist.ID,
	})
	_, _ = q.UpsertAlbum(context.Background(), dbq.UpsertAlbumParams{
		Title: "Mango", SortTitle: "Mango", ArtistID: artist.ID,
	})

	w := doListLibraryAlbums(h, user, "limit=10")
	if w.Code != http.StatusOK {
		t.Fatalf("status = %d, body = %s", w.Code, w.Body.String())
	}
	var got Page[AlbumRef]
	if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
		t.Fatalf("decode: %v", err)
	}
	if got.Total != 3 {
		t.Errorf("total = %d, want 3", got.Total)
	}
	titles := []string{got.Items[0].Title, got.Items[1].Title, got.Items[2].Title}
	if titles[0] != "Apple" || titles[1] != "Mango" || titles[2] != "Zoo" {
		t.Errorf("titles = %v, want [Apple Mango Zoo]", titles)
	}
	if got.Items[0].SortTitle != "Apple" {
		t.Errorf("sort_title = %q, want Apple", got.Items[0].SortTitle)
	}
}

func TestLibraryAlbums_Paging(t *testing.T) {
	h, pool := testHandlers(t)
	user := seedUser(t, pool, "alice", "pw", false)
	q := dbq.New(pool)
	artist, _ := q.UpsertArtist(context.Background(), dbq.UpsertArtistParams{
		Name: "ArtistA", SortName: "ArtistA",
	})
	for _, title := range []string{"A", "B", "C", "D"} {
		_, _ = q.UpsertAlbum(context.Background(), dbq.UpsertAlbumParams{
			Title: title, SortTitle: title, ArtistID: artist.ID,
		})
	}

	w := doListLibraryAlbums(h, user, "limit=2&offset=2")
	if w.Code != http.StatusOK {
		t.Fatalf("status = %d", w.Code)
	}
	var got Page[AlbumRef]
	_ = json.Unmarshal(w.Body.Bytes(), &got)
	if got.Total != 4 || got.Limit != 2 || got.Offset != 2 {
		t.Errorf("envelope = %+v, want total=4 limit=2 offset=2", got)
	}
	if len(got.Items) != 2 || got.Items[0].Title != "C" || got.Items[1].Title != "D" {
		t.Errorf("items = %v, want [C D]", got.Items)
	}
}
