// Package validator implements the home-side Telegram validator gRPC service: it
// verifies Mini App initData and Login Widget data with the bot token's HMAC and
// never calls the Bot API. The gateway calls it during the auth.telegram and
// link.telegram edge operations. It holds the token only as the HMAC secret, so it
// can run on the main host with no VPN and no Telegram egress (ARCHITECTURE.md §12).
package validator

import (
	"context"

	"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"
)

// Server implements the validation subset of telegramv1.TelegramServer; the
// delivery methods (Notify, SendToUser, SendToGameChannel) are intentionally
// unimplemented here — those run on the remote bot over the bot-link.
type Server struct {
	telegramv1.UnimplementedTelegramServer
	initValidator   initdata.Validator
	widgetValidator loginwidget.Validator
}

// NewServer builds the validator from the two HMAC validators bound to the token.
func NewServer(iv initdata.Validator, wv loginwidget.Validator) *Server {
	return &Server{initValidator: iv, widgetValidator: wv}
}

// ValidateInitData verifies Mini App launch data against the bot's token and
// returns the user identity.
func (s *Server) ValidateInitData(_ context.Context, req *telegramv1.ValidateInitDataRequest) (*telegramv1.ValidateInitDataResponse, error) {
	u, err := s.initValidator.Validate(req.GetInitData())
	if err != nil {
		return nil, status.Error(codes.InvalidArgument, err.Error())
	}
	return &telegramv1.ValidateInitDataResponse{
		ExternalId:   u.ExternalID,
		Username:     u.Username,
		FirstName:    u.FirstName,
		LanguageCode: u.LanguageCode,
	}, nil
}

// ValidateLoginWidget verifies Login Widget authorization data against the bot's
// token and returns the user identity, for attaching a Telegram identity to an
// existing account.
func (s *Server) ValidateLoginWidget(_ context.Context, req *telegramv1.ValidateLoginWidgetRequest) (*telegramv1.ValidateLoginWidgetResponse, error) {
	u, err := s.widgetValidator.Validate(req.GetData())
	if err != nil {
		return nil, status.Error(codes.InvalidArgument, err.Error())
	}
	return &telegramv1.ValidateLoginWidgetResponse{
		ExternalId: u.ExternalID,
		Username:   u.Username,
		FirstName:  u.FirstName,
	}, nil
}
