package port_test

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

	"gitea.dwysokinski.me/twhelp/corev3/internal/adapter"
	"gitea.dwysokinski.me/twhelp/corev3/internal/app"
	"gitea.dwysokinski.me/twhelp/corev3/internal/bun/buntest"
	"gitea.dwysokinski.me/twhelp/corev3/internal/port"
	"github.com/stretchr/testify/require"
)

type apiHTTPHandlerConfig struct {
	options []port.APIHTTPHandlerOption
}

func newAPIHTTPHandler(tb testing.TB, opts ...func(cfg *apiHTTPHandlerConfig)) http.Handler {
	tb.Helper()

	cfg := &apiHTTPHandlerConfig{}

	for _, opt := range opts {
		opt(cfg)
	}

	bunDB := buntest.NewSQLiteDB(tb)
	buntest.NewFixture(bunDB).Load(tb, context.Background(), os.DirFS("testdata/api"), "fixture.yml")

	versionRepo := adapter.NewVersionBunRepository(bunDB)
	serverRepo := adapter.NewServerBunRepository(bunDB)
	tribeRepo := adapter.NewTribeBunRepository(bunDB)
	playerRepo := adapter.NewPlayerBunRepository(bunDB)

	return port.NewAPIHTTPHandler(
		app.NewVersionService(versionRepo),
		app.NewServerService(serverRepo, nil, nil),
		app.NewTribeService(tribeRepo, nil, nil),
		app.NewPlayerService(playerRepo, nil, nil, nil),
		cfg.options...,
	)
}

func doRequest(h http.Handler, method, target string, body io.Reader) *http.Response {
	return doCustomRequest(h, httptest.NewRequest(method, target, body))
}

func doCustomRequest(h http.Handler, r *http.Request) *http.Response {
	rr := httptest.NewRecorder()
	h.ServeHTTP(rr, r)
	return rr.Result()
}

func decodeJSON[T any](tb testing.TB, r io.Reader) T {
	tb.Helper()
	var res T
	require.NoError(tb, json.NewDecoder(r).Decode(&res))
	return res
}
