package model

import (
	"strings"
	"time"

	"github.com/google/uuid"
	"github.com/zitadel/oidc/v3/pkg/oidc"
)

// AuthRequest also implements the op.AuthRequest interface
type AuthRequest struct {
	ID          uuid.UUID
	ClientID    string
	Scopes      []string
	RedirectURI string
	State       string
	Nonce       string

	ResponseType string

	CreationDate time.Time
	AuthTime     time.Time

	// TODO mapping to claims to be added I guess

	CodeChallenge       string
	CodeChallengeMethod string

	BackendID uuid.UUID
	Backend   *Backend

	UserID uuid.UUID

	DoneVal bool
}

func (a AuthRequest) GetID() string {
	return a.ID.String()
}

func (a AuthRequest) GetACR() string {
	return "" // TODO: the hell is ACR???
}

func (a AuthRequest) GetAMR() []string {
	return []string{} // TODO: the hell is this???
}

func (a AuthRequest) GetAudience() []string {
	return []string{a.ID.String()} // TODO: check if we need to return something else
}

func (a AuthRequest) GetAuthTime() time.Time {
	return a.AuthTime
}

func (a AuthRequest) GetClientID() string {
	return a.ClientID
}

func (a AuthRequest) GetCodeChallenge() *oidc.CodeChallenge {
	return &oidc.CodeChallenge{
		Challenge: a.CodeChallenge,
		Method:    oidc.CodeChallengeMethod(a.CodeChallengeMethod),
	}
}

func (a AuthRequest) GetNonce() string {
	return a.Nonce
}

func (a AuthRequest) GetRedirectURI() string {
	return a.RedirectURI
}

func (a AuthRequest) GetResponseType() oidc.ResponseType {
	return oidc.ResponseType(a.ResponseType)
}

func (a AuthRequest) GetResponseMode() oidc.ResponseMode {
	return oidc.ResponseModeQuery // TODO: check if this is good
}

func (a AuthRequest) GetScopes() []string {
	return a.Scopes
}

func (a AuthRequest) GetState() string {
	return a.State
}

func (a AuthRequest) GetSubject() string {
	return a.UserID.String()
}

func (a AuthRequest) Done() bool {
	return a.DoneVal
}

func (a *AuthRequest) FromOIDCAuthRequest(req *oidc.AuthRequest, backendID uuid.UUID) {
	a.ID = uuid.New()
	a.ClientID = req.ClientID
	a.Scopes = strings.Split(req.Scopes.String(), " ")
	a.RedirectURI = req.RedirectURI
	a.State = req.State
	a.Nonce = req.Nonce
	a.ResponseType = string(req.ResponseType)
	a.CreationDate = time.Now().UTC()
	a.CodeChallenge = req.CodeChallenge
	a.CodeChallengeMethod = string(req.CodeChallengeMethod)
	a.BackendID = backendID
}
