// Code generated by op-codegen - DO NOT EDIT

package onepassword

import (
	"context"
	"encoding/json"

	"github.com/1password/onepassword-sdk-go/internal"
)

// The Items API holds all operations the SDK client can perform on 1Password items.
type ItemsAPI interface {
	// Create a new item.
	Create(ctx context.Context, params ItemCreateParams) (Item, error)

	// Create items in batch, within a single vault.
	CreateAll(ctx context.Context, vaultID string, params []ItemCreateParams) (ItemsUpdateAllResponse, error)

	// Get an item by vault and item ID.
	Get(ctx context.Context, vaultID string, itemID string) (Item, error)

	// Get items by vault and their item IDs.
	GetAll(ctx context.Context, vaultID string, itemIds []string) (ItemsGetAllResponse, error)

	// Update an existing item.
	Put(ctx context.Context, item Item) (Item, error)

	// Delete an item.
	Delete(ctx context.Context, vaultID string, itemID string) error

	// Delete items in batch, within a single vault.
	DeleteAll(ctx context.Context, vaultID string, itemIds []string) (ItemsDeleteAllResponse, error)

	// Archive an item.
	Archive(ctx context.Context, vaultID string, itemID string) error

	// List items based on filters.
	List(ctx context.Context, vaultID string, filters ...ItemListFilter) ([]ItemOverview, error)

	// ----- Sub APIs - these methods are used to access subordinate function groups -----
	Shares() ItemsSharesAPI
	Files() ItemsFilesAPI
}

type ItemsSource struct {
	*internal.InnerClient
	SharesAPI ItemsSharesAPI
	FilesAPI  ItemsFilesAPI
}

func NewItemsSource(inner *internal.InnerClient) ItemsAPI {
	return &ItemsSource{InnerClient: inner, SharesAPI: NewItemsSharesSource(inner), FilesAPI: NewItemsFilesSource(inner)}
}

func (i ItemsSource) Shares() ItemsSharesAPI {
	return i.SharesAPI
}
func (i ItemsSource) Files() ItemsFilesAPI {
	return i.FilesAPI
}

// Create a new item.
func (i ItemsSource) Create(ctx context.Context, params ItemCreateParams) (Item, error) {
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsCreate", map[string]interface{}{
		"params": params,
	})
	if err != nil {
		return Item{}, err
	}
	var result Item
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return Item{}, err
	}
	return result, nil
}

// Create items in batch, within a single vault.
func (i ItemsSource) CreateAll(ctx context.Context, vaultID string, params []ItemCreateParams) (ItemsUpdateAllResponse, error) {
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsCreateAll", map[string]interface{}{
		"vault_id": vaultID,
		"params":   params,
	})
	if err != nil {
		return ItemsUpdateAllResponse{}, err
	}
	var result ItemsUpdateAllResponse
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return ItemsUpdateAllResponse{}, err
	}
	return result, nil
}

// Get an item by vault and item ID.
func (i ItemsSource) Get(ctx context.Context, vaultID string, itemID string) (Item, error) {
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsGet", map[string]interface{}{
		"vault_id": vaultID,
		"item_id":  itemID,
	})
	if err != nil {
		return Item{}, err
	}
	var result Item
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return Item{}, err
	}
	return result, nil
}

// Get items by vault and their item IDs.
func (i ItemsSource) GetAll(ctx context.Context, vaultID string, itemIds []string) (ItemsGetAllResponse, error) {
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsGetAll", map[string]interface{}{
		"vault_id": vaultID,
		"item_ids": itemIds,
	})
	if err != nil {
		return ItemsGetAllResponse{}, err
	}
	var result ItemsGetAllResponse
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return ItemsGetAllResponse{}, err
	}
	return result, nil
}

// Update an existing item.
func (i ItemsSource) Put(ctx context.Context, item Item) (Item, error) {
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsPut", map[string]interface{}{
		"item": item,
	})
	if err != nil {
		return Item{}, err
	}
	var result Item
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return Item{}, err
	}
	return result, nil
}

// Delete an item.
func (i ItemsSource) Delete(ctx context.Context, vaultID string, itemID string) error {
	_, err := clientInvoke(ctx, i.InnerClient, "ItemsDelete", map[string]interface{}{
		"vault_id": vaultID,
		"item_id":  itemID,
	})
	return err
}

// Delete items in batch, within a single vault.
func (i ItemsSource) DeleteAll(ctx context.Context, vaultID string, itemIds []string) (ItemsDeleteAllResponse, error) {
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsDeleteAll", map[string]interface{}{
		"vault_id": vaultID,
		"item_ids": itemIds,
	})
	if err != nil {
		return ItemsDeleteAllResponse{}, err
	}
	var result ItemsDeleteAllResponse
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return ItemsDeleteAllResponse{}, err
	}
	return result, nil
}

// Archive an item.
func (i ItemsSource) Archive(ctx context.Context, vaultID string, itemID string) error {
	_, err := clientInvoke(ctx, i.InnerClient, "ItemsArchive", map[string]interface{}{
		"vault_id": vaultID,
		"item_id":  itemID,
	})
	return err
}

// List items based on filters.
func (i ItemsSource) List(ctx context.Context, vaultID string, filters ...ItemListFilter) ([]ItemOverview, error) {
	if filters == nil {
		filters = []ItemListFilter{}
	}
	resultString, err := clientInvoke(ctx, i.InnerClient, "ItemsList", map[string]interface{}{
		"vault_id": vaultID,
		"filters":  filters,
	})
	if err != nil {
		return nil, err
	}
	var result []ItemOverview
	err = json.Unmarshal([]byte(*resultString), &result)
	if err != nil {
		return nil, err
	}
	return result, nil
}
