package infra

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

func TestSPAHandler(t *testing.T) {
	mapFS := fstest.MapFS{
		"index.html": {
			Data: []byte(`<!doctype html><html><body>SPA</body></html>`),
		},
		"assets/app.js": {
			Data: []byte(`console.log("app")`),
		},
	}

	handler := SPAHandler(mapFS, "index.html")

	t.Run("sirve archivo estatico existente con status 200", func(t *testing.T) {
		req := httptest.NewRequest(http.MethodGet, "/assets/app.js", nil)
		rec := httptest.NewRecorder()
		handler.ServeHTTP(rec, req)

		if rec.Code != http.StatusOK {
			t.Errorf("got status %d, want %d", rec.Code, http.StatusOK)
		}
		body := rec.Body.String()
		if body != `console.log("app")` {
			t.Errorf("unexpected body: %q", body)
		}
	})

	t.Run("ruta inexistente hace fallback a index.html con Content-Type text/html", func(t *testing.T) {
		req := httptest.NewRequest(http.MethodGet, "/some/route", nil)
		rec := httptest.NewRecorder()
		handler.ServeHTTP(rec, req)

		if rec.Code != http.StatusOK {
			t.Errorf("got status %d, want %d", rec.Code, http.StatusOK)
		}
		ct := rec.Header().Get("Content-Type")
		if ct != "text/html; charset=utf-8" {
			t.Errorf("got Content-Type %q, want %q", ct, "text/html; charset=utf-8")
		}
		body := rec.Body.String()
		if body == "" {
			t.Error("expected non-empty body (index.html)")
		}
	})

	t.Run("raiz retorna index.html", func(t *testing.T) {
		req := httptest.NewRequest(http.MethodGet, "/", nil)
		rec := httptest.NewRecorder()
		handler.ServeHTTP(rec, req)

		if rec.Code != http.StatusOK {
			t.Errorf("got status %d, want %d", rec.Code, http.StatusOK)
		}
		ct := rec.Header().Get("Content-Type")
		if ct != "text/html; charset=utf-8" {
			t.Errorf("got Content-Type %q, want %q", ct, "text/html; charset=utf-8")
		}
	})

	t.Run("path con .. retorna 400", func(t *testing.T) {
		req := httptest.NewRequest(http.MethodGet, "/foo/../bar", nil)
		rec := httptest.NewRecorder()
		handler.ServeHTTP(rec, req)

		if rec.Code != http.StatusBadRequest {
			t.Errorf("got status %d, want %d", rec.Code, http.StatusBadRequest)
		}
	})
}
