// @oagen-ignore-file

package workos

import (
	
	
	
	
	
)

// SSOAuthorizationURLParams are parameters for building an SSO authorization URL.
type SSOAuthorizationURLParams struct {
	RedirectURI         string
	ClientID            string // if empty, uses client's configured clientID
	Provider            *string
	ConnectionID        *string
	OrganizationID      *string
	DomainHint          *string
	LoginHint           *string
	State               *string
	CodeChallenge       *string
	CodeChallengeMethod *string
}

// GetSSOAuthorizationURL builds an SSO authorization URL client-side.
func ( *Client) ( SSOAuthorizationURLParams) (string, error) {
	 := .ClientID
	if  == "" {
		 = .clientID
	}
	if  == "" {
		return "", fmt.Errorf("workos: client_id is required for SSO authorization URL")
	}
	if .RedirectURI == "" {
		return "", fmt.Errorf("workos: redirect_uri is required for SSO authorization URL")
	}

	 := .baseURL
	if  == "" {
		 = defaultBaseURL
	}

	,  := url.Parse( + "/sso/authorize")
	if  != nil {
		return "", fmt.Errorf("workos: failed to parse SSO authorization URL: %w", )
	}

	 := .Query()
	.Set("client_id", )
	.Set("redirect_uri", .RedirectURI)
	.Set("response_type", "code")

	if .Provider != nil {
		.Set("provider", *.Provider)
	}
	if .ConnectionID != nil {
		.Set("connection_id", *.ConnectionID)
	}
	if .OrganizationID != nil {
		.Set("organization_id", *.OrganizationID)
	}
	if .DomainHint != nil {
		.Set("domain_hint", *.DomainHint)
	}
	if .LoginHint != nil {
		.Set("login_hint", *.LoginHint)
	}
	if .State != nil {
		.Set("state", *.State)
	}
	if .CodeChallenge != nil {
		.Set("code_challenge", *.CodeChallenge)
	}
	if .CodeChallengeMethod != nil {
		.Set("code_challenge_method", *.CodeChallengeMethod)
	}

	.RawQuery = .Encode()
	return .String(), nil
}

// SSOPKCEAuthorizationURLResult holds the URL and PKCE verifier.
type SSOPKCEAuthorizationURLResult struct {
	URL          string
	CodeVerifier string
	State        string
}

// GetSSOPKCEAuthorizationURL generates PKCE parameters and builds an SSO authorization URL.
func ( *Client) ( SSOAuthorizationURLParams) (*SSOPKCEAuthorizationURLResult, error) {
	,  := GeneratePKCEPair()
	if  != nil {
		return nil, fmt.Errorf("workos: failed to generate PKCE pair: %w", )
	}

	.CodeChallenge = &.CodeChallenge
	.CodeChallengeMethod = &.CodeChallengeMethod

	// Generate a random state if not provided.
	 := ""
	if .State != nil {
		 = *.State
	} else {
		 := make([]byte, 32)
		if ,  := rand.Read();  != nil {
			return nil, fmt.Errorf("workos: failed to generate random state: %w", )
		}
		 = base64.RawURLEncoding.EncodeToString()
		.State = &
	}

	,  := .GetSSOAuthorizationURL()
	if  != nil {
		return nil, 
	}

	return &SSOPKCEAuthorizationURLResult{
		URL:          ,
		CodeVerifier: .CodeVerifier,
		State:        ,
	}, nil
}

// SSOPKCECodeExchangeParams for SSO PKCE code exchange.
type SSOPKCECodeExchangeParams struct {
	Code         string
	CodeVerifier string
}

// SSOPKCECodeExchange exchanges an SSO authorization code with PKCE.
func ( *Client) ( context.Context,  SSOPKCECodeExchangeParams,  ...RequestOption) (*SSOTokenResponse, error) {
	 := .clientID
	 := map[string]interface{}{
		"grant_type":    "authorization_code",
		"code":          .Code,
		"code_verifier": .CodeVerifier,
	}
	if  != "" {
		["client_id"] = 
	}
	if .apiKey != "" {
		["client_secret"] = .apiKey
	}

	var  SSOTokenResponse
	,  := .request(, "POST", "/sso/token", nil, , &, )
	if  != nil {
		return nil, 
	}
	return &, nil
}

// SSOLogoutParams holds parameters for SSO logout.
type SSOLogoutParams struct {
	SessionID string
	ReturnTo  *string
}

// SSOLogout initiates a logout flow.
// First obtains a logout token via AuthorizeLogout, then builds the logout redirect URL.
func ( *Client) ( context.Context,  SSOLogoutParams,  ...RequestOption) (string, error) {
	// Step 1: Call AuthorizeLogout to get a logout token.
	,  := .SSO().AuthorizeLogout(, &SSOAuthorizeLogoutParams{
		ProfileID: .SessionID,
	}, ...)
	if  != nil {
		return "", 
	}

	// Step 2: Build the logout redirect URL.
	 := .baseURL
	if  == "" {
		 = defaultBaseURL
	}

	,  := url.Parse( + "/sso/logout")
	if  != nil {
		return "", fmt.Errorf("workos: failed to parse logout URL: %w", )
	}

	 := .Query()
	.Set("token", .LogoutToken)
	if .ReturnTo != nil {
		.Set("return_to", *.ReturnTo)
	}

	.RawQuery = .Encode()
	return .String(), nil
}