package api

import (
	"agent/client/events"
	"agent/commons/utils"
	"context"
	"encoding/json"

	"github.com/google/uuid"
)

type ClientKey struct {
	ProjectName string         `json:"project_name"`
	ProjectUuid UUID           `json:"project_uuid"`
	Uuid        UUID           `json:"uuid"`
	Name        string         `json:"name"`
	Value       string         `json:"value"`
	Settings    map[string]any `json:"settings"`
	CreatorUuid UUID           `json:"creator_uuid"`
	Created     int64          `json:"created"`
	Updated     int64          `json:"updated"`
}

func ClientKeyCreate(ctx context.Context, client IClient,
	args ClientKeyCreateArgs,
) (res ClientKey, err error) {
	event, err := EventClientKeyCreate(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGet(ctx context.Context, client IClient,
	args ClientKeyGetArgs,
) (res ClientKey, err error) {
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGetByUuid(ctx context.Context, client IClient,
	uuid uuid.UUID,
) (res ClientKey, err error) {
	args := ClientKeyGetArgs{
		Uuid: uuid,
	}
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGetByUuidRaw(ctx context.Context, client IClient,
	uuid uuid.UUID,
) (res ClientKey, err error) {
	args := ClientKeyGetArgs{
		Uuid: uuid,
		Raw:  utils.PointerTo(true),
	}
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGetByName(ctx context.Context, client IClient,
	projectUuid uuid.UUID, name string,
) (res ClientKey, err error) {
	args := ClientKeyGetArgs{
		ProjectUuid: projectUuid,
		Name:        name,
	}
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGetByNameRaw(ctx context.Context, client IClient,
	projectUuid uuid.UUID, name string,
) (res ClientKey, err error) {
	args := ClientKeyGetArgs{
		ProjectUuid: projectUuid,
		Name:        name,
		Raw:         utils.PointerTo(true),
	}
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGetByValue(ctx context.Context, client IClient,
	projectUuid uuid.UUID, value string,
) (res ClientKey, err error) {
	args := ClientKeyGetArgs{
		ProjectUuid: projectUuid,
		Value:       value,
	}
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyGetByValueRaw(ctx context.Context, client IClient,
	projectUuid uuid.UUID, value string,
) (res ClientKey, err error) {
	args := ClientKeyGetArgs{
		ProjectUuid: projectUuid,
		Value:       value,
		Raw:         utils.PointerTo(true),
	}
	event, err := EventClientKeyGet(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyUpdate(ctx context.Context, client IClient,
	args ClientKeyUpdateArgs,
) (res ClientKey, err error) {
	event, err := EventClientKeyUpdate(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyDelete(ctx context.Context, client IClient,
	uuid uuid.UUID,
) error {
	event, err := EventClientKeyDelete(uuid)
	if err != nil {
		return err
	}
	_, err = events.ExecuteAndGetData(ctx, client, event)
	return err
}

func ClientKeyList(ctx context.Context, client IClient,
	args ClientKeyListArgs,
) (res []ClientKey, err error) {
	event, err := EventClientKeyList(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyListByProject(ctx context.Context, client IClient,
	args ClientKeyListByProjectArgs,
) (res []ClientKey, err error) {
	event, err := EventClientKeyListByProject(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyListByAgentGroups(ctx context.Context, client IClient,
	args ClientKeyListByAgentGroupsArgs,
) (res []ClientKey, err error) {
	event, err := EventClientKeyListByAgentGroups(args)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}

func ClientKeyListAll(ctx context.Context, client IClient,
	args ...ClientKeyListAllArgs,
) (res []ClientKey, err error) {
	event, err := EventClientKeyListAll(args...)
	if err != nil {
		return res, nil
	}
	data, err := events.ExecuteAndGetData(ctx, client, event)
	if err != nil {
		return res, err
	}
	return res, json.Unmarshal(data, &res)
}
