package api

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

type ProjectCreateArgs struct {
	// UUID-проекта (если не задан, будет сгенерирован)
	Uuid UUID `json:"uuid"`
	// Имя проекта
	Name string `json:"name"`
	// Описание проекта
	Description string `json:"description"`
	// Настройки проекта (опционально)
	Settings map[string]any `json:"settings"`
}

func EventProjectCreate(args ProjectCreateArgs) (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.Project},
		daction.Create,
		meta,
	), nil
}

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

type ProjectGetArgs struct {
	// UUID проекта (если на задан, должен быть указан Name)
	Uuid UUID `json:"uuid,omitempty"`
	// Имя проекта (если не задан, должен быть указан Uuid)
	Name string `json:"name,omitempty"`
	// Если true, будет возвращена базовая информация о проекте без настроек (опционально)
	Raw *bool `json:"raw,omitempty"`
}

func EventProjectGet(args ProjectGetArgs) (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.Project},
		daction.Get,
		meta,
	), nil
}

type ProjectListArgs struct {
	Kind   string                `json:"kind"`
	Filter ProjectListFilterArgs `json:"filter"`
	Raw    *bool                 `json:"raw,omitempty"`
}

type ProjectListFilterArgs struct {
	AgentUuid UUID   `json:"agent_uuid,omitempty"`
	Search    string `json:"search,omitempty"`
}

func EventProjectList(args ProjectListArgs) (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.Project},
		daction.List,
		meta,
	), nil
}

func EventProjectListByAgent(agentUuid UUID, search ...string) (IEvent, error) {
	s := ""
	if len(search) > 0 {
		s = search[0]
	}
	args := ProjectListArgs{
		Kind: "by_agent",
		Filter: ProjectListFilterArgs{
			AgentUuid: agentUuid,
			Search:    s,
		},
	}
	return EventProjectList(args)
}

func EventProjectListAll(search ...string) (IEvent, error) {
	s := ""
	if len(search) > 0 {
		s = search[0]
	}
	args := ProjectListArgs{
		Kind: "all",
		Filter: ProjectListFilterArgs{
			Search: s,
		},
	}
	return EventProjectList(args)
}

type ProjectUpdateArgs struct {
	// UUID проекта
	Uuid UUID `json:"uuid"`
	// Новое имя проекта (опционально)
	Name string `json:"name,omitempty"`
	// Новое описание проекта (опционально)
	Description string `json:"description,omitempty"`
	// Новые настройки проекта (опционально)
	Settings map[string]any `json:"settings,omitempty"`
}

func EventProjectUpdate(args ProjectUpdateArgs) (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.Project},
		daction.Update,
		meta,
	), nil
}
