package api

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

func EventAgentTokenGet(tokenUuid UUID, raw ...bool) (IEvent, error) {
	meta := map[string]any{
		"uuid": tokenUuid,
	}
	if len(raw) > 0 {
		meta["raw"] = raw[0]
	}
	return events.NewEvent(
		dkind.UserToService,
		[]Category{dcategory.Service, dcategory.Agent, dcategory.Token},
		daction.Get,
		meta,
	), nil
}

type AgentTokenDeleteArgs struct {
	AgentUuids []UUID   `json:"agent_uuids,omitempty"`
	Uuids      []UUID   `json:"uuids,omitempty"`
	Tokens     []string `json:"tokens,omitempty"`
}

func EventAgentTokenDelete(args AgentTokenDeleteArgs) (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.Token},
		daction.Delete,
		meta,
	), nil
}

type AgentTokenListArgs struct {
	Kind    string                   `json:"kind"`
	Filter  AgentTokenListFilterOpts `json:"filter,omitempty"`
	Offset  int64                    `json:"offset,omitempty"`
	Limit   int64                    `json:"limit,omitempty"`
	Reverse *bool                    `json:"reverse,omitempty"`
	Count   *bool                    `json:"count,omitempty"`
	Admin   *bool                    `json:"admin,omitempty"`
	Raw     *bool                    `json:"raw,omitempty"`
}

type AgentTokenListFilterOpts struct {
	ProjectUuids    []UUID `json:"project_uuids,omitempty"`
	AgentGroupUuids []UUID `json:"agent_group_uuids,omitempty"`
	UserGroupUuids  []UUID `json:"user_group_uuids,omitempty"`
	AgentUuid       UUID   `json:"agent_uuid,omitempty"`
	Search          string `json:"search,omitempty"`
}

func EventAgentTokenList(args AgentTokenListArgs) (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.Token},
		daction.List,
		meta,
	), nil
}

type AgentTokenListByProjectsAndUserGroupsArgs struct {
	ProjectUuids   []UUID
	UserGroupUuids []UUID
	Offset         int64
	Limit          int64
	Reverse        *bool
	Count          *bool
	Admin          *bool
}

func EventAgentTokenListByProjectsAndUserGroups(
	args AgentTokenListByProjectsAndUserGroupsArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind: "by_projects_and_user_groups",
		Filter: AgentTokenListFilterOpts{
			ProjectUuids:   args.ProjectUuids,
			UserGroupUuids: args.UserGroupUuids,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}

type AgentTokenListByProjectsAndAgentGroupsArgs struct {
	ProjectUuids    []UUID
	AgentGroupUuids []UUID
	Offset          int64
	Limit           int64
	Reverse         *bool
	Count           *bool
	Admin           *bool
}

func EventAgentTokenListByProjectsAndAgentGroups(
	args AgentTokenListByProjectsAndAgentGroupsArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind: "by_projects_and_agent_groups",
		Filter: AgentTokenListFilterOpts{
			ProjectUuids:    args.ProjectUuids,
			AgentGroupUuids: args.AgentGroupUuids,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}

type AgentTokenListByProjectsArgs struct {
	ProjectUuids []UUID
	Offset       int64
	Limit        int64
	Reverse      *bool
	Count        *bool
	Admin        *bool
}

func EventAgentTokenListByProjects(
	args AgentTokenListByProjectsArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind: "by_projects",
		Filter: AgentTokenListFilterOpts{
			ProjectUuids: args.ProjectUuids,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}

type AgentTokenListByUserGroupsArgs struct {
	UserGroupUuids []UUID
	Offset         int64
	Limit          int64
	Reverse        *bool
	Count          *bool
	Admin          *bool
}

func EventAgentTokenListByUserGroups(
	args AgentTokenListByUserGroupsArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind: "by_user_groups",
		Filter: AgentTokenListFilterOpts{
			UserGroupUuids: args.UserGroupUuids,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}

type AgentTokenListByAgentGroupsArgs struct {
	AgentGroupUuids []UUID
	Offset          int64
	Limit           int64
	Reverse         *bool
	Count           *bool
	Admin           *bool
}

func EventAgentTokenListByAgentGroups(
	args AgentTokenListByAgentGroupsArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind: "by_agent_groups",
		Filter: AgentTokenListFilterOpts{
			AgentGroupUuids: args.AgentGroupUuids,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}

type AgentTokenListByAgentArgs struct {
	AgentUuid UUID
	Offset    int64
	Limit     int64
	Reverse   *bool
	Count     *bool
	Admin     *bool
}

func EventAgentTokenListByAgent(
	args AgentTokenListByAgentArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind: "by_agent",
		Filter: AgentTokenListFilterOpts{
			AgentUuid: args.AgentUuid,
		},
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}

type AgentTokenListAllArgs struct {
	Offset  int64 `json:"offset,omitempty"`
	Limit   int64 `json:"limit,omitempty"`
	Reverse *bool `json:"reverse,omitempty"`
	Count   *bool `json:"count,omitempty"`
	Admin   *bool `json:"admin,omitempty"`
}

func EventAgentTokenListAll(
	args AgentTokenListAllArgs, raw ...bool,
) (IEvent, error) {
	args_ := AgentTokenListArgs{
		Kind:    "all",
		Offset:  args.Offset,
		Limit:   args.Limit,
		Reverse: args.Reverse,
		Count:   args.Count,
		Admin:   args.Admin,
	}
	if len(raw) > 0 {
		args_.Raw = &raw[0]
	} else {
		args_.Raw = utils.PointerTo(false)
	}
	return EventAgentTokenList(args_)
}
