package extension

import (
	"sort"

	"git.perx.ru/perxis/perxis-go/pkg/collections"
	"git.perx.ru/perxis/perxis-go/pkg/references"
	"git.perx.ru/perxis/perxis-go/pkg/schema"
	"git.perx.ru/perxis/perxis-go/pkg/schema/field"
	"git.perx.ru/perxis/perxis-go/pkg/schema/validate"
)

const (
	ExtensionsCollectionID   = "space_extensions"
	ExtensionsCollectionName = "Настройки/Расширения"

	ActionsCollectionID   = "space_actions"
	ActionsCollectionName = "Настройки/Действия"
)

// NewActionsCollection - создает коллекцию для хранения действий расширений в пространстве
func NewActionsCollection(spaceID, envID string) *collections.Collection {
	sch := schema.New(
		"action", field.String(validate.Required()).SetTitle("Действие").SetTextSearch(true),
		"extension", field.String().SetTitle("Расширение (Deprecated)"),
		"name", field.String().SetTitle("Название").SetTextSearch(true),
		"description", field.String().SetTitle("Описание"),
		"icon", field.String().SetTitle("Название иконки").WithUI(&field.UI{Widget: "Icon"}),
		"image", references.Field([]string{"media"}).SetTitle("Изображение").WithUI(&field.UI{Widget: "Media"}),
		"kind", field.Number(
			field.NumberFormatInt,
			validate.Enum(getEnumOpt(ActionKindName)...),
		).SetTitle("Вид").WithUI(&field.UI{Widget: "Select"}),
		"autorun", field.Bool().SetTitle("Автозапуск").
			SetDescription("Действие выполняется автоматически каждый раз при загрузке приложения").
			WithUI(&field.UI{Widget: "Checkbox"}),
		"confirm", field.Bool().SetTitle("С подтверждением").
			SetDescription("Пользователь должен подтвердить запуск действия").
			WithUI(&field.UI{Widget: "Checkbox"}),
		"target", field.Number(
			field.NumberFormatInt,
			validate.Enum(getEnumOpt(ActionTargetName)...),
		).SetTitle("Отображение результата действия").WithUI(&field.UI{Widget: "Select"}),
		"view", field.Number(
			field.NumberFormatInt,
			validate.Enum(getEnumOpt(ActionViewName)...),
		).SetTitle("Отображение действия в интерфейсе").WithUI(&field.UI{Widget: "Select"}),
		"parent", field.String().SetTitle("Идентификатор родительского действия"),
		"order", field.Number(field.NumberFormatInt).SetTitle("Порядок отображения").
			SetDescription("Порядок отображения действия в интерфейсе (Для пунктов меню)"),
		"groups", field.Array(field.String().SetAdditionalValues()).SetTitle("Группы").
			SetDescription("Группировка действий в пользовательском интерфейсе").
			WithUI(&field.UI{Widget: "SelectList"}),
		"classes", field.Array(field.String().SetAdditionalValues()).SetTitle("Класс").
			WithUI(&field.UI{Widget: "SelectList"}).
			SetDescription("Классы данных, к которым применимо действие").
			SetIndexed(true),
		"refs", field.Array(references.Field(nil)).SetTitle("Ссылки").
			WithUI(&field.UI{Widget: "BlockList"}),
		"params_collection", field.String().SetTitle("Коллекция параметров").
			SetDescription("ID коллекции для хранения параметров действия").WithUI(&field.UI{Widget: "Collection"}),
		"navigation_action", field.Bool().SetTitle("Навигация (Deprecated)").
			SetDescription("Выполняется переход пользователя в пользовательском интерфейсе").
			WithUI(&field.UI{Widget: "Checkbox"}),
		"navigation_route", field.String().SetTitle("Путь в интерфейсе (Deprecated)"),
	)

	// Includes
	sch.SetIncludes(
		field.Include{Ref: "hoop_item_options", Optional: true},
	)

	// UI
	sch.Field.UI.ListView = &field.View{Options: map[string]interface{}{
		"fields":    []interface{}{"name", "action", "kind", "updated_at", "updated_by", "state"},
		"sort":      []interface{}{"name"},
		"page_size": float64(50),
	}}

	sch.Field.UI.Options["title"] = "name"
	sch.Field.UI.Options["subtitle"] = "action"
	sch.Field.UI.Options["collection_icon"] = "SettingOutlined/RocketOutlined"

	return &collections.Collection{
		ID:      ActionsCollectionID,
		SpaceID: spaceID,
		EnvID:   envID,
		Name:    ActionsCollectionName,
		Schema:  sch,
		Hidden:  true,
	}
}

func getEnumOpt(opts map[int32]string) []validate.EnumOpt {
	keys := make([]int32, 0, len(opts))
	for k := range opts {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool {
		return keys[i] < keys[j]
	})

	enum := make([]validate.EnumOpt, len(opts))
	for i, n := range keys {
		enum[i] = validate.EnumOpt{Name: opts[n], Value: float64(n)}
	}
	return enum
}

// NewExtensionsCollection - создает коллекцию для хранения статусов расширений в пространстве
func NewExtensionsCollection(spaceID, envID string) *collections.Collection {
	sch := schema.New(
		"id", field.String(validate.Required()).SetUnique(true).SetTitle("Расширение"),
		"title", field.String().SetTitle("Название"),
		"version", field.String().SetTitle("Установленная версия"),
		"status_error", field.String().SetTitle("Ошибка"),
		"status_msg", field.String().SetTitle("Сообщение"),
		"extension_state", field.Number(
			field.NumberFormatInt,
			validate.Enum(
				validate.EnumOpt{Name: StateInstalled.String(), Value: float64(StateInstalled)},
				validate.EnumOpt{Name: StateFail.String(), Value: float64(StateFail)},
				validate.EnumOpt{Name: StatePending.String(), Value: float64(StatePending)},
				validate.EnumOpt{Name: StateInProgress.String(), Value: float64(StateInProgress)},
			),
		).SetTitle("Состояние").WithUI(&field.UI{Widget: "Select"}),
	)

	// UI
	sch.Field.UI.ListView = &field.View{Options: map[string]interface{}{
		"fields":    []interface{}{"id", "title", "extension_state", "updated_at", "updated_by"},
		"sort":      []interface{}{"title"},
		"page_size": float64(50),
	}}

	sch.Field.UI.Options["title"] = "title"
	sch.Field.UI.Options["subtitle"] = "id"
	sch.Field.UI.Options["key"] = "id"
	sch.Field.UI.Options["collection_icon"] = "SettingOutlined/ApiOutlined"

	return &collections.Collection{
		ID:      ExtensionsCollectionID,
		SpaceID: spaceID,
		EnvID:   envID,
		Name:    ExtensionsCollectionName,
		Schema:  sch,
		Hidden:  true,
	}
}