package api

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

type AgentBaseTagCreateArgs struct {
	Uuid  UUID   `json:"uuid,omitempty"`
	Name  string `json:"name"`
	Color string `json:"color,omitempty"`
}

func EventAgentBaseTagCreate(args AgentBaseTagCreateArgs) (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.Agent, dcategory.Tag, dcategory.Base},
		daction.Create,
		meta,
	), nil
}

type AgentBaseTagGetArgs struct {
	Uuid UUID   `json:"uuid,omitempty"`
	Name string `json:"name,omitempty"`
}

func EventAgentBaseTagGet(args AgentBaseTagGetArgs) (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.Agent, dcategory.Tag, dcategory.Base},
		daction.Get,
		meta,
	), nil
}

func EventAgentBaseTagGetByUuid(uuid UUID) (IEvent, error) {
	args := AgentBaseTagGetArgs{
		Uuid: uuid,
	}
	return EventAgentBaseTagGet(args)
}

func EventAgentBaseTagGetByName(name string) (IEvent, error) {
	args := AgentBaseTagGetArgs{
		Name: name,
	}
	return EventAgentBaseTagGet(args)
}

type AgentBaseTagDeleteArgs struct {
	Uuids []UUID   `json:"uuid_list,omitempty"`
	Names []string `json:"name_list,omitempty"`
}

func EventAgentBaseTagDelete(args AgentBaseTagDeleteArgs) (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.Agent, dcategory.Tag, dcategory.Base},
		daction.Delete,
		meta,
	), nil
}

type AgentBaseTagListArggs struct {
	Filter  AgentBaseTagListFilterOpts `json:"filter,omitempty"`
	Offset  int64                      `json:"offset,omitempty"`
	Limit   int64                      `json:"limit,omitempty"`
	Reverse *bool                      `json:"reverse,omitempty"`
}

type AgentBaseTagListFilterOpts struct {
	Search string `json:"search,omitempty"`
}

func EventAgentBaseTagList(args AgentBaseTagListArggs) (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.Agent, dcategory.Tag, dcategory.Base},
		daction.List,
		meta,
	), nil
}

type AgentBaseTagUpdateArgs struct {
	Uuid    UUID   `json:"uuid"`
	OldName string `json:"old_name,omitempty"`
	Name    string `json:"name,omitempty"`
	Color   string `json:"color,omitempty"`
}

func EventAgentBaseTagUpdate(args AgentBaseTagUpdateArgs) (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.Agent, dcategory.Tag, dcategory.Base},
		daction.Update,
		meta,
	), nil
}

func EventAgentBaseTagUpdateByUuid(uuid UUID, name string, color string) (IEvent, error) {
	args := AgentBaseTagUpdateArgs{
		Uuid:  uuid,
		Name:  name,
		Color: color,
	}
	return EventAgentBaseTagUpdate(args)
}

func EventAgentBaseTagUpdateByName(oldName string, name string, color string) (IEvent, error) {
	args := AgentBaseTagUpdateArgs{
		OldName: oldName,
		Name:    name,
		Color:   color,
	}
	return EventAgentBaseTagUpdate(args)
}

type AgentTagAddArgs struct {
	AgentUuid UUID   `json:"agent_uuid"`
	Uuid      UUID   `json:"tag_uuid"`
	Name      string `json:"tag_name"`
	Color     string `json:"tag_color,omitempty"`
	Position  *int   `json:"position,omitempty"`
}

func EventAgentTagAdd(args AgentTagAddArgs) (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.Agent, dcategory.Tag},
		daction.Add,
		meta,
	), nil
}

type AgentTagDeleteArgs struct {
	AgentUuid UUID   `json:"agent_uuid"`
	Uuid      UUID   `json:"tag_uuid,omitempty"`
	Name      string `json:"tag_name,omitempty"`
}

func EventAgentTagDelete(args AgentTagDeleteArgs) (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.Agent, dcategory.Tag},
		daction.Delete,
		meta,
	), nil
}

func EventAgentTagDeleteByUuid(agentUuid UUID, tagUuid UUID) (IEvent, error) {
	args := AgentTagDeleteArgs{
		AgentUuid: agentUuid,
		Uuid:      tagUuid,
	}
	return EventAgentTagDelete(args)
}

func EventAgentTagDeleteByName(agentUuid UUID, tagName string) (IEvent, error) {
	args := AgentTagDeleteArgs{
		AgentUuid: agentUuid,
		Name:      tagName,
	}
	return EventAgentTagDelete(args)
}

func EventAgentTagList(agentUuid UUID) (IEvent, error) {
	meta := map[string]any{
		"agent_uuid": agentUuid,
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Agent, dcategory.Tag},
		daction.List,
		meta,
	), nil
}

type AgentTagSetItem struct {
	Name  string `json:"name"`
	Color string `json:"color"`
}

type AgentTagSetArgs struct {
	AgentUuid UUID              `json:"agent_uuid"`
	TagUuids  []UUID            `json:"uuid_list,omitempty"`
	TagNames  []AgentTagSetItem `json:"name_list,omitempty"`
}

func EventAgentTagSet(args AgentTagSetArgs) (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.Agent, dcategory.Tag},
		daction.Set,
		meta,
	), nil
}
