package infra

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

func TestOauth2Refresh_Success(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_ = r.ParseForm()
		if got := r.PostForm.Get("grant_type"); got != "refresh_token" {
			t.Errorf("grant_type = %q", got)
		}
		if got := r.PostForm.Get("refresh_token"); got != "rt-old" {
			t.Errorf("refresh_token = %q", got)
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(map[string]any{
			"access_token":  "at-new",
			"refresh_token": "rt-new",
			"token_type":    "Bearer",
			"expires_in":    1800,
		})
	}))
	defer srv.Close()

	cfg := OAuthConfig{TokenURL: srv.URL, ClientID: "c", ClientSecret: "s"}
	tokens, err := Oauth2Refresh(cfg, "rt-old")
	if err != nil {
		t.Fatalf("Oauth2Refresh: %v", err)
	}
	if tokens.AccessToken != "at-new" {
		t.Errorf("AccessToken = %q", tokens.AccessToken)
	}
	if tokens.RefreshToken != "rt-new" {
		t.Errorf("RefreshToken = %q", tokens.RefreshToken)
	}
}

func TestOauth2Refresh_PreservesRefreshTokenIfProviderOmits(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(map[string]any{
			"access_token": "at-new",
			"token_type":   "Bearer",
			"expires_in":   1800,
			// no refresh_token
		})
	}))
	defer srv.Close()

	cfg := OAuthConfig{TokenURL: srv.URL}
	tokens, err := Oauth2Refresh(cfg, "rt-keep")
	if err != nil {
		t.Fatalf("Oauth2Refresh: %v", err)
	}
	if tokens.RefreshToken != "rt-keep" {
		t.Errorf("esperaba conservar rt-keep, got %q", tokens.RefreshToken)
	}
}

func TestOauth2Refresh_EmptyToken(t *testing.T) {
	cfg := OAuthConfig{TokenURL: "http://x"}
	if _, err := Oauth2Refresh(cfg, ""); err == nil {
		t.Fatal("esperaba error con refresh vacio")
	}
}
