package adapter_test

import (
	"context"
	"os"
	"testing"

	"gitea.dwysokinski.me/twhelp/corev3/internal/adapter"
	"gitea.dwysokinski.me/twhelp/corev3/internal/bun/buntest"
	"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
	"github.com/uptrace/bun"
)

type versionRepository interface {
	List(ctx context.Context, params domain.ListVersionsParams) (domain.Versions, error)
	ListCount(
		ctx context.Context,
		params domain.ListVersionsParams,
	) (domain.Versions, int, error)
}

type serverRepository interface {
	CreateOrUpdate(ctx context.Context, params ...domain.CreateServerParams) error
	List(ctx context.Context, params domain.ListServersParams) (domain.Servers, error)
	Update(ctx context.Context, key string, params domain.UpdateServerParams) error
}

type tribeRepository interface {
	CreateOrUpdate(ctx context.Context, params ...domain.CreateTribeParams) error
	UpdateDominance(ctx context.Context, serverKey string, numPlayerVillages int) error
	List(ctx context.Context, params domain.ListTribesParams) (domain.Tribes, error)
	Delete(ctx context.Context, serverKey string, ids ...int) error
}

type playerRepository interface {
	CreateOrUpdate(ctx context.Context, params ...domain.CreatePlayerParams) error
	List(ctx context.Context, params domain.ListPlayersParams) (domain.Players, error)
	Delete(ctx context.Context, serverKey string, ids ...int) error
}

type villageRepository interface {
	CreateOrUpdate(ctx context.Context, params ...domain.CreateVillageParams) error
	List(ctx context.Context, params domain.ListVillagesParams) (domain.Villages, error)
	Delete(ctx context.Context, serverKey string, ids ...int) error
}

type ennoblementRepository interface {
	Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
	List(ctx context.Context, params domain.ListEnnoblementsParams) (domain.Ennoblements, error)
}

type tribeChangeRepository interface {
	Create(ctx context.Context, params ...domain.CreateTribeChangeParams) error
	List(ctx context.Context, params domain.ListTribeChangesParams) (domain.TribeChanges, error)
}

type repositories struct {
	version     versionRepository
	server      serverRepository
	tribe       tribeRepository
	player      playerRepository
	village     villageRepository
	ennoblement ennoblementRepository
	tribeChange tribeChangeRepository
}

func newBunDBRepositories(tb testing.TB, bunDB *bun.DB) repositories {
	tb.Helper()

	buntest.NewFixture(bunDB).Load(tb, context.Background(), os.DirFS("testdata"), "fixture.yml")

	return repositories{
		version:     adapter.NewVersionBunRepository(bunDB),
		server:      adapter.NewServerBunRepository(bunDB),
		tribe:       adapter.NewTribeBunRepository(bunDB),
		player:      adapter.NewPlayerBunRepository(bunDB),
		village:     adapter.NewVillageBunRepository(bunDB),
		ennoblement: adapter.NewEnnoblementBunRepository(bunDB),
		tribeChange: adapter.NewTribeChangeBunRepository(bunDB),
	}
}
