package validator

import (
	"context"
	"testing"

	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	telegramv1 "scrabble/pkg/proto/telegram/v1"
	"scrabble/platform/telegram/internal/initdata"
	"scrabble/platform/telegram/internal/loginwidget"
)

// stubValidator returns a fixed user / error from Validate.
type stubValidator struct {
	user initdata.User
	err  error
}

func (s stubValidator) Validate(string) (initdata.User, error) { return s.user, s.err }

// stubWidgetValidator returns a fixed user / error from the Login Widget Validate.
type stubWidgetValidator struct {
	user loginwidget.User
	err  error
}

func (s stubWidgetValidator) Validate(string) (loginwidget.User, error) { return s.user, s.err }

func TestValidateInitData(t *testing.T) {
	want := initdata.User{ExternalID: "42", Username: "neo", FirstName: "Thomas", LanguageCode: "en-GB"}
	srv := NewServer(stubValidator{user: want}, stubWidgetValidator{})
	resp, err := srv.ValidateInitData(context.Background(), &telegramv1.ValidateInitDataRequest{InitData: "x"})
	if err != nil {
		t.Fatalf("validate: %v", err)
	}
	if resp.GetExternalId() != "42" || resp.GetUsername() != "neo" || resp.GetFirstName() != "Thomas" || resp.GetLanguageCode() != "en-GB" {
		t.Errorf("resp = %+v, want %+v", resp, want)
	}

	bad := NewServer(stubValidator{err: initdata.ErrInvalidInitData}, stubWidgetValidator{})
	if _, err := bad.ValidateInitData(context.Background(), &telegramv1.ValidateInitDataRequest{}); status.Code(err) != codes.InvalidArgument {
		t.Errorf("err code = %v, want InvalidArgument", status.Code(err))
	}
}

func TestValidateLoginWidget(t *testing.T) {
	want := loginwidget.User{ExternalID: "42", Username: "neo", FirstName: "Thomas"}
	srv := NewServer(stubValidator{}, stubWidgetValidator{user: want})
	resp, err := srv.ValidateLoginWidget(context.Background(), &telegramv1.ValidateLoginWidgetRequest{Data: "x"})
	if err != nil {
		t.Fatalf("validate: %v", err)
	}
	if resp.GetExternalId() != "42" || resp.GetUsername() != "neo" || resp.GetFirstName() != "Thomas" {
		t.Errorf("resp = %+v, want %+v", resp, want)
	}

	bad := NewServer(stubValidator{}, stubWidgetValidator{err: loginwidget.ErrInvalidLoginWidget})
	if _, err := bad.ValidateLoginWidget(context.Background(), &telegramv1.ValidateLoginWidgetRequest{}); status.Code(err) != codes.InvalidArgument {
		t.Errorf("err code = %v, want InvalidArgument", status.Code(err))
	}
}
