package api

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

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

func TestHandleGetMe_ReturnsAuthenticatedUser(t *testing.T) {
	h, pool := testHandlers(t)
	user := seedUser(t, pool, "alice", "hunter2", true)

	req := httptest.NewRequest(http.MethodGet, "/api/me", nil)
	req = withUser(req, user)
	w := httptest.NewRecorder()
	h.handleGetMe(w, req)

	if w.Code != http.StatusOK {
		t.Fatalf("status = %d body = %s", w.Code, w.Body.String())
	}
	var got meProfileResp
	if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
		t.Fatalf("decode: %v", err)
	}
	if got.Username != "test-alice" || !got.IsAdmin {
		t.Errorf("user = %+v, want test-alice/admin", got)
	}
	if got.DisplayName != nil {
		t.Errorf("DisplayName = %v, want nil for a user with no profile set", *got.DisplayName)
	}
	if got.Email != nil {
		t.Errorf("Email = %v, want nil for a user with no profile set", *got.Email)
	}
}

// Drift #578 regression guard: a user whose profile fields ARE set
// must see them in the /api/me response. Previously this handler
// emitted the narrower UserView so Android Settings → Profile saw
// display_name=null and email=null on every read, wiped the form
// fields, and submitting from that blank state destroyed the user's
// stored values via the "empty string clears to NULL" semantics of
// PUT /api/me/profile.
func TestHandleGetMe_IncludesDisplayNameAndEmail(t *testing.T) {
	h, pool := testHandlers(t)
	user := seedUser(t, pool, "alice", "hunter2", false)

	displayName := "Alice Liddell"
	email := "alice@example.com"
	updated, err := dbq.New(pool).UpdateUserProfile(context.Background(), dbq.UpdateUserProfileParams{
		ID:          user.ID,
		DisplayName: &displayName,
		Email:       &email,
	})
	if err != nil {
		t.Fatalf("UpdateUserProfile: %v", err)
	}

	req := httptest.NewRequest(http.MethodGet, "/api/me", nil)
	req = withUser(req, updated)
	w := httptest.NewRecorder()
	h.handleGetMe(w, req)

	if w.Code != http.StatusOK {
		t.Fatalf("status = %d body = %s", w.Code, w.Body.String())
	}
	var got meProfileResp
	if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
		t.Fatalf("decode: %v", err)
	}
	if got.DisplayName == nil || *got.DisplayName != displayName {
		t.Errorf("DisplayName = %v, want %q", got.DisplayName, displayName)
	}
	if got.Email == nil || *got.Email != email {
		t.Errorf("Email = %v, want %q", got.Email, email)
	}
}

func TestHandleGetMe_MissingContextReturns500(t *testing.T) {
	h, _ := testHandlers(t)
	req := httptest.NewRequest(http.MethodGet, "/api/me", nil)
	w := httptest.NewRecorder()
	h.handleGetMe(w, req)

	if w.Code != http.StatusInternalServerError {
		t.Errorf("status = %d, want 500 (context should be populated by RequireUser)", w.Code)
	}
	_ = dbq.User{} // keep the import used
}
