// Code generated by Fern. DO NOT EDIT.

package client

import (
	context "context"
	management "github.com/auth0/go-auth0/v2/management"
	core "github.com/auth0/go-auth0/v2/management/core"
	internal "github.com/auth0/go-auth0/v2/management/internal"
	option "github.com/auth0/go-auth0/v2/management/option"
	clientgrants "github.com/auth0/go-auth0/v2/management/organizations/clientgrants"
	enabledconnections "github.com/auth0/go-auth0/v2/management/organizations/enabledconnections"
	invitations "github.com/auth0/go-auth0/v2/management/organizations/invitations"
	client "github.com/auth0/go-auth0/v2/management/organizations/members/client"
	http "net/http"
)

type Client struct {
	WithRawResponse    *RawClient
	ClientGrants       *clientgrants.Client
	EnabledConnections *enabledconnections.Client
	Invitations        *invitations.Client
	Members            *client.Client

	options *core.RequestOptions
	baseURL string
	caller  *internal.Caller
}

func NewClient(options *core.RequestOptions) *Client {
	return &Client{
		ClientGrants:       clientgrants.NewClient(options),
		EnabledConnections: enabledconnections.NewClient(options),
		Invitations:        invitations.NewClient(options),
		Members:            client.NewClient(options),
		WithRawResponse:    NewRawClient(options),
		options:            options,
		baseURL:            options.BaseURL,
		caller: internal.NewCaller(
			&internal.CallerParams{
				Client:      options.HTTPClient,
				MaxAttempts: options.MaxAttempts,
			},
		),
	}
}

// Retrieve detailed list of all Organizations available in your tenant. For more information, see Auth0 Organizations.
//
// This endpoint supports two types of pagination:
// <ul>
// <li>Offset pagination</li>
// <li>Checkpoint pagination</li>
// </ul>
//
// Checkpoint pagination must be used if you need to retrieve more than 1000 organizations.
//
// <h2>Checkpoint Pagination</h2>
//
// To search by checkpoint, use the following parameters:
// <ul>
// <li><code>from</code>: Optional id from which to start selection.</li>
// <li><code>take</code>: The total number of entries to retrieve when using the <code>from</code> parameter. Defaults to 50.</li>
// </ul>
//
// <b>Note</b>: The first time you call this endpoint using checkpoint pagination, omit the <code>from</code> parameter. If there are more results, a <code>next</code> value is included in the response. You can use this for subsequent API calls. When <code>next</code> is no longer included in the response, no pages are remaining.
func (c *Client) List(
	ctx context.Context,
	request *management.ListOrganizationsRequestParameters,
	opts ...option.RequestOption,
) (*core.Page[*management.Organization], error) {
	options := core.NewRequestOptions(opts...)
	baseURL := internal.ResolveBaseURL(
		options.BaseURL,
		c.baseURL,
		"https://%7BTENANT%7D.auth0.com/api/v2",
	)
	endpointURL := baseURL + "/organizations"
	queryParams, err := internal.QueryValues(request)
	if err != nil {
		return nil, err
	}
	headers := internal.MergeHeaders(
		c.options.ToHeader(),
		options.ToHeader(),
	)
	prepareCall := func(pageRequest *internal.PageRequest[*string]) *internal.CallParams {
		if pageRequest.Cursor != nil {
			queryParams.Set("from", *pageRequest.Cursor)
		}
		nextURL := endpointURL
		if len(queryParams) > 0 {
			nextURL += "?" + queryParams.Encode()
		}
		return &internal.CallParams{
			URL:             nextURL,
			Method:          http.MethodGet,
			Headers:         headers,
			MaxAttempts:     options.MaxAttempts,
			BodyProperties:  options.BodyProperties,
			QueryParameters: options.QueryParameters,
			Client:          options.HTTPClient,
			Response:        pageRequest.Response,
			ErrorDecoder:    internal.NewErrorDecoder(management.ErrorCodes),
		}
	}
	readPageResponse := func(response *management.ListOrganizationsPaginatedResponseContent) *internal.PageResponse[*string, *management.Organization] {
		var zeroValue *string
		next := response.Next
		results := response.Organizations
		return &internal.PageResponse[*string, *management.Organization]{
			Next:    next,
			Results: results,
			Done:    next == zeroValue,
		}
	}
	pager := internal.NewCursorPager(
		c.caller,
		prepareCall,
		readPageResponse,
	)
	return pager.GetPage(ctx, request.From)
}

// Create a new Organization within your tenant.  To learn more about Organization settings, behavior, and configuration options, review <a href="https://auth0.com/docs/manage-users/organizations/create-first-organization">Create Your First Organization</a>.
func (c *Client) Create(
	ctx context.Context,
	request *management.CreateOrganizationRequestContent,
	opts ...option.RequestOption,
) (*management.CreateOrganizationResponseContent, error) {
	response, err := c.WithRawResponse.Create(
		ctx,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Retrieve details about a single Organization specified by name.
func (c *Client) GetByName(
	ctx context.Context,
	// name of the organization to retrieve.
	name string,
	opts ...option.RequestOption,
) (*management.GetOrganizationByNameResponseContent, error) {
	response, err := c.WithRawResponse.GetByName(
		ctx,
		name,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Retrieve details about a single Organization specified by ID.
func (c *Client) Get(
	ctx context.Context,
	// ID of the organization to retrieve.
	id string,
	opts ...option.RequestOption,
) (*management.GetOrganizationResponseContent, error) {
	response, err := c.WithRawResponse.Get(
		ctx,
		id,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}

// Remove an Organization from your tenant.  This action cannot be undone.
//
// <b>Note</b>: Members are automatically disassociated from an Organization when it is deleted. However, this action does <b>not</b> delete these users from your tenant.
func (c *Client) Delete(
	ctx context.Context,
	// Organization identifier.
	id string,
	opts ...option.RequestOption,
) error {
	_, err := c.WithRawResponse.Delete(
		ctx,
		id,
		opts...,
	)
	if err != nil {
		return err
	}
	return nil
}

// Update the details of a specific <a href="https://auth0.com/docs/manage-users/organizations/configure-organizations/create-organizations">Organization</a>, such as name and display name, branding options, and metadata.
func (c *Client) Update(
	ctx context.Context,
	// ID of the organization to update.
	id string,
	request *management.UpdateOrganizationRequestContent,
	opts ...option.RequestOption,
) (*management.UpdateOrganizationResponseContent, error) {
	response, err := c.WithRawResponse.Update(
		ctx,
		id,
		request,
		opts...,
	)
	if err != nil {
		return nil, err
	}
	return response.Body, nil
}
