package api

import (
	"agent/client/events"
	"agent/commons/utils"
	"agent/defines/devent/daction"
	"agent/defines/devent/dcategory"
	"agent/defines/devent/dkind"
)

type ClientHandshakeCreateArgs struct {
	ProjectUuid UUID   `json:"project_uuid"`
	Uuid        UUID   `json:"uuid,omitempty"`
	Name        string `json:"name"`
	Value       string `json:"value,omitempty"`
	PrivKey     string `json:"priv_key,omitempty"`
}

func EventClientHandshakeCreate(args ClientHandshakeCreateArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Client, dcategory.Handshake, dcategory.Key},
		daction.Create,
		meta,
	), nil
}

func EventClientHandshakeDelete(uuid UUID) (IEvent, error) {
	meta := map[string]any{
		"uuid": uuid,
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Client, dcategory.Handshake, dcategory.Key},
		daction.Delete,
		meta,
	), nil
}

type ClientHandshakeGetArgs struct {
	Uuid        UUID   `json:"uuid,omitempty"`
	ProjectUuid UUID   `json:"project_uuid,omitempty"`
	Value       string `json:"value,omitempty"`
	Name        string `json:"name,omitempty"`
	Raw         *bool  `json:"raw,omitempty"`
}

func EventClientHandshakeGet(args ClientHandshakeGetArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Client, dcategory.Handshake, dcategory.Key},
		daction.Get,
		meta,
	), nil
}

type ClientHandshakeUpdateArgs struct {
	Uuid    UUID   `json:"uuid"`
	Name    string `json:"name,omitempty"`
	Value   string `json:"value,omitempty"`
	PrivKey string `json:"priv_key,omitempty"`
}

func EventClientHandshakeUpdate(args ClientHandshakeUpdateArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Client, dcategory.Handshake, dcategory.Key},
		daction.Update,
		meta,
	), nil
}

type ClientHandshakeListArgs struct {
	Kind    string                        `json:"kind"`
	Filter  ClientHandshakeListFilterArgs `json:"filter,omitempty"`
	Offset  int64                         `json:"offset,omitempty"`
	Limit   int64                         `json:"limit,omitempty"`
	Reverse *bool                         `json:"reverse,omitempty"`
	Raw     *bool                         `json:"raw,omitempty"`
}

type ClientHandshakeListFilterArgs struct {
	ProjectUuid UUID   `json:"project_uuid,omitempty"`
	Search      string `json:"search,omitempty"`
}

func EventClientHandshakeList(args ClientHandshakeListArgs) (IEvent, error) {
	meta, err := utils.ConvertTo[map[string]any](args)
	if err != nil {
		return nil, err
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Client, dcategory.Handshake, dcategory.Key},
		daction.List,
		meta,
	), nil
}

type ClientHandshakeListByProjectArgs struct {
	ProjectUuid UUID   `json:"project_uuid"`
	Search      string `json:"search,omitempty"`
	Offset      int64  `json:"offset,omitempty"`
	Limit       int64  `json:"limit,omitempty"`
	Reverse     *bool  `json:"reverse,omitempty"`
}

func EventClientHandshakeListByProject(args ClientHandshakeListByProjectArgs) (IEvent, error) {
	args_ := ClientHandshakeListArgs{
		Kind: "by_project",
		Filter: ClientHandshakeListFilterArgs{
			ProjectUuid: args.ProjectUuid,
			Search:      args.Search,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
	}
	return EventClientHandshakeList(args_)
}

type ClientHandshakeListAllArgs struct {
	Search  string `json:"search,omitempty"`
	Offset  int64  `json:"offset,omitempty"`
	Limit   int64  `json:"limit,omitempty"`
	Reverse *bool  `json:"reverse,omitempty"`
}

func EventClientHandshakeListAll(args ...ClientHandshakeListAllArgs) (IEvent, error) {
	args_ := ClientHandshakeListArgs{
		Kind: "all",
	}
	if len(args) > 0 {
		a := args[0]
		args_.Filter.Search = a.Search
		args_.Offset = a.Offset
		args_.Limit = a.Limit
		args_.Reverse = a.Reverse
	}
	return EventClientHandshakeList(args_)
}
