package users

import (
	"context"
	"net/http"

	telemetry "code.justin.tv/amzn/TwitchTelemetry"
	"code.justin.tv/live/autohost/internal/metrics"

	"code.justin.tv/foundation/twitchclient"

	"code.justin.tv/creator-collab/log/errors"
	"code.justin.tv/live/autohost/internal/logfield"
	users "code.justin.tv/web/users-service/client/usersclient_internal"
	userModels "code.justin.tv/web/users-service/models"
	"github.com/cactus/go-statsd-client/statsd"
)

const metricsServiceName = "Users"

// InternalUsersClient is an interface wrapper around users.InternalClient
type InternalUsersClient interface {
	users.InternalClient
}

// Service wraps the UsersService client
type Service struct {
	Client InternalUsersClient
}

func New(url string, statsClient statsd.Statter, sampleReporter *telemetry.SampleReporter) (*Service, error) {
	usersClient, err := users.NewClient(twitchclient.ClientConf{
		Host:           url,
		Stats:          statsClient,
		TimingXactName: "users_service",
		Transport: twitchclient.TransportConf{
			MaxIdleConnsPerHost: 10,
		},
		RoundTripperWrappers: []func(http.RoundTripper) http.RoundTripper{
			metrics.NewTwitchClientMiddlewareWrapper(&metrics.TwitchClientMiddlewareWrapperConfig{
				SampleReporter: sampleReporter,
			}),
		},
	})
	if err != nil {
		return nil, errors.Wrap(err, "failed to create users client")
	}

	return &Service{
		Client: usersClient,
	}, nil
}

// GetChannelIDs returns a map of channel logins to channel ids
func (s *Service) GetChannelIDs(ctx context.Context, logins []string) (map[string]string, error) {
	ctx = metrics.WithTwitchClientOperation(ctx, metricsServiceName, "GetUsers")

	params := &userModels.FilterParams{
		Logins:                     logins,
		InlineIdentifierValidation: true,
	}
	users, err := s.Client.GetUsers(ctx, params, nil)
	if err != nil {
		return nil, errors.Wrap(err, "users - batch get user failed", errors.Fields{
			logfield.UserLogins: logins,
		})
	}

	loginIDMap := map[string]string{}
	for _, user := range users.Results {
		if user.Login != nil {
			loginIDMap[*user.Login] = user.ID
		}
	}

	return loginIDMap, nil
}
