package auth

import (
	"cmp"
	"errors"
	"fmt"
	"slices"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/account/idl/pbgen/proto/account"

	"github.com/tidbcloud/tidb-management-service/tempo-wrapper/pkg/utils"
)

func getAuth0User(ctx *gin.Context, u *account.GetAuthUserResponse) (*User, error) {
	if u == nil {
		return nil, errors.New("failed to get auth info")
	}

	user := &User{
		User: u.User,
	}

	user.Org = &account.Org{
		Id: u.Org.Id,
	}

	user.Projects = u.AvailableProjects

	if u.IsImpersonated {
		// in order to prevent affecting the impersonate function
		id, err := utils.ParseProjIDFromPath(ctx.Request.URL.Path)
		if err != nil {
			return nil, fmt.Errorf("failed to get project id: %w", err)
		}
		user.Projects = []*account.Project{{Status: ProjectStatusActive, Id: id}}
	}

	if len(user.Projects) == 0 {
		return nil, errors.New("no project in this organization")
	}

	if ctx.Param("project_id") != "" {
		projectId, err := strconv.ParseUint(ctx.Param("project_id"), 10, 64)
		if err != nil {
			return nil, fmt.Errorf("invalid project id: %w", err)
		}
		user.Projects = []*account.Project{{Status: ProjectStatusActive, Id: projectId}}
	} else {
		slices.SortFunc(user.Projects, func(a, b *account.Project) int {
			return cmp.Compare(a.Id, b.Id)
		})
	}

	return user, nil
}
