package model

import (
	"time"

	"github.com/zitadel/oidc/v3/pkg/oidc"
	"github.com/zitadel/oidc/v3/pkg/op"
)

// ClientConfig represents the configuration for a OIDC client app
type ClientConfig struct {
	ID           string
	Secret       string
	RedirectURIs []string
	TrustedPeers []string
	Name         string
	AuthRequest  *AuthRequest
}

// Client represents an OIDC client app
type Client struct {
	ClientConfig
}

func (c Client) GetID() string {
	return c.ClientConfig.ID
}

func (c Client) RedirectURIs() []string {
	return c.ClientConfig.RedirectURIs
}

func (c Client) PostLogoutRedirectURIs() []string {
	return nil
}

func (c Client) ApplicationType() op.ApplicationType {
	return op.ApplicationTypeWeb // TODO: should we support more?
}

func (c Client) AuthMethod() oidc.AuthMethod {
	return oidc.AuthMethodBasic
}

func (c Client) ResponseTypes() []oidc.ResponseType {
	return []oidc.ResponseType{oidc.ResponseTypeCode}
}

func (c Client) GrantTypes() []oidc.GrantType {
	return []oidc.GrantType{oidc.GrantTypeCode, oidc.GrantTypeRefreshToken, oidc.GrantTypeTokenExchange}
}

// LoginURL returns the login URL for a given client app and auth request.
// This login url should be the authorization URL for the selected OIDC backend
func (c Client) LoginURL(authRequestID string) string {
	if authRequestID == "" {
		return "" // we don't have a request, let's return nothing
	}

	return "/perform_auth?request_id=" + authRequestID
}

func (c Client) AccessTokenType() op.AccessTokenType {
	return op.AccessTokenTypeJWT
}

func (c Client) IDTokenLifetime() time.Duration {
	return 1 * time.Hour
}

func (c Client) DevMode() bool {
	return true
}

func (c Client) RestrictAdditionalIdTokenScopes() func(scopes []string) []string {
	return func(scopes []string) []string {
		return scopes
	}
}

func (c Client) RestrictAdditionalAccessTokenScopes() func(scopes []string) []string {
	return func(scopes []string) []string {
		return scopes
	}
}

func (c Client) IsScopeAllowed(scope string) bool {
	return true
}

func (c Client) IDTokenUserinfoClaimsAssertion() bool {
	return true
}

func (c Client) ClockSkew() time.Duration {
	return 0
}
