package authx_test

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

	"aijianzhan/platform/internal/authx"
)

func TestIssueAndParseToken(t *testing.T) {
	cfg := authx.JWTConfig{AccessSecret: "test-secret", AccessExpire: 3600}
	tok, exp, err := authx.IssueToken(cfg, 9, 42, "owner", 0)
	if err != nil {
		t.Fatal(err)
	}
	if tok == "" || exp <= 0 {
		t.Fatal("empty token")
	}
	claims, err := authx.ParseToken(cfg, tok)
	if err != nil {
		t.Fatal(err)
	}
	if claims.TenantID != 9 || claims.UserID != 42 {
		t.Fatalf("claims mismatch: %+v", claims)
	}
}

func TestMiddlewareRequiresJWT(t *testing.T) {
	cfg := authx.JWTConfig{AccessSecret: "test-secret", AccessExpire: 3600}
	mw := authx.Middleware(cfg, false)
	called := false
	h := mw(func(w http.ResponseWriter, r *http.Request) {
		called = true
		w.WriteHeader(http.StatusOK)
	})

	req := httptest.NewRequest(http.MethodGet, "/x", nil)
	rr := httptest.NewRecorder()
	h(rr, req)
	if rr.Code != http.StatusUnauthorized || called {
		t.Fatalf("expected 401 without token, got %d called=%v", rr.Code, called)
	}

	tok, _, err := authx.IssueToken(cfg, 1, 2, "owner", 0)
	if err != nil {
		t.Fatal(err)
	}
	req2 := httptest.NewRequest(http.MethodGet, "/x", nil)
	req2.Header.Set("Authorization", "Bearer "+tok)
	rr2 := httptest.NewRecorder()
	h(rr2, req2)
	if rr2.Code != http.StatusOK || !called {
		t.Fatalf("expected 200 with token, got %d", rr2.Code)
	}
	if authx.TenantID(req2.Context()) != 0 {
		// context is on the request passed to next; check via handler
	}
}

func TestMiddlewareInjectsClaims(t *testing.T) {
	cfg := authx.JWTConfig{AccessSecret: "test-secret", AccessExpire: 3600}
	tok, _, _ := authx.IssueToken(cfg, 7, 8, "editor", 0)
	mw := authx.Middleware(cfg, false)
	var gotTenant, gotUser int64
	h := mw(func(w http.ResponseWriter, r *http.Request) {
		gotTenant = authx.TenantID(r.Context())
		gotUser = authx.UserID(r.Context())
		w.WriteHeader(http.StatusOK)
	})
	req := httptest.NewRequest(http.MethodGet, "/x", nil)
	req.Header.Set("Authorization", "Bearer "+tok)
	rr := httptest.NewRecorder()
	h(rr, req)
	if gotTenant != 7 || gotUser != 8 {
		t.Fatalf("got tenant=%d user=%d", gotTenant, gotUser)
	}
}
