package gomodules

import (
	"fmt"
	"rubric/utils"
	"strings"
)

// Module описывает один раздел справочника
type Module struct {
	Key         string   // основной ключ для -topic
	Aliases     []string // сокращения
	Title       string   // название в меню
	Description string   // краткое описание
	Run         func()   // функция вывода
}

// All — список всех модулей в порядке меню
var All = []Module{
	BasicsModule,
	StructuresModule,
	CompositeModule,
	// сюда будут добавляться новые модули
}

// Find ищет модуль по ключу или алиасу
func Find(key string) (Module, bool) {
	key = strings.ToLower(strings.TrimSpace(key))
	for _, m := range All {
		if m.Key == key {
			return m, true
		}
		for _, a := range m.Aliases {
			if a == key {
				return m, true
			}
		}
	}
	return Module{}, false
}

// ShowMenu отображает интерактивное меню
func ShowMenu() {
	utils.Header("Справочник Go")

	fmt.Printf("  %s%sДоступные разделы:%s\n\n", utils.ColorBold, utils.ColorWhite, utils.ColorReset)

	for i, m := range All {
		aliases := ""
		if len(m.Aliases) > 0 {
			aliases = fmt.Sprintf("%s [%s]%s", utils.ColorDim, strings.Join(m.Aliases, ", "), utils.ColorReset)
		}
		fmt.Printf("  %s%s%2d.%s %-10s %s%-36s%s%s\n",
			utils.ColorBold, utils.ColorCyan, i+1, utils.ColorReset,
			utils.ColorYellow+utils.ColorBold+m.Key+utils.ColorReset,
			utils.ColorWhite, m.Title, utils.ColorReset,
			aliases,
		)
		fmt.Printf("      %s%s%s\n", utils.ColorDim, m.Description, utils.ColorReset)
		fmt.Println()
	}

	fmt.Printf("  %s%sВведите номер или ключ раздела (q — выход):%s ", utils.ColorBold, utils.ColorGreen, utils.ColorReset)
}

// ShowHelp выводит справку по ключам
func ShowHelp() {
	utils.Header("rubric — справка по использованию")

	utils.Section("Запуск")
	utils.Command("./rubric", "интерактивное меню")
	utils.Command("./rubric -topic basics", "открыть раздел напрямую")
	utils.Command("./rubric -topic b", "по короткому алиасу")
	utils.Command("./rubric -list", "список всех разделов")
	utils.Command("./rubric -help", "эта справка")
	fmt.Println()

	utils.Section("Доступные разделы и ключи")
	for _, m := range All {
		keys := append([]string{m.Key}, m.Aliases...)
		fmt.Printf("  %s%-10s%s  %-32s  %sключи: %s%s\n",
			utils.ColorBold+utils.ColorCyan, m.Key, utils.ColorReset,
			m.Title,
			utils.ColorDim, strings.Join(keys, ", "), utils.ColorReset,
		)
	}

	utils.Footer()
}

// ListModules выводит краткий список модулей
func ListModules() {
	fmt.Printf("\n%s%sРазделы Go:%s\n\n", utils.ColorBold, utils.ColorCyan, utils.ColorReset)
	for i, m := range All {
		fmt.Printf("  %s%d.%s %-10s — %s\n",
			utils.ColorDim, i+1, utils.ColorReset,
			utils.ColorYellow+utils.ColorBold+m.Key+utils.ColorReset,
			m.Title,
		)
	}
	fmt.Println()
}

// Keywords возвращает ключевые слова для поиска по модулю
func Keywords(key string) []string {
	kw := map[string][]string{
		"basics": {
			"установка", "install", "go build", "go test", "go run", "go fmt",
			"go vet", "go doc", "go mod", "go get", "тестирование", "сборка",
			"компиляция", "кросс-компиляция", "GOOS", "GOARCH", "golangci-lint",
			"бенчмарк", "benchmark", "покрытие", "coverage", "go env", "GOPATH",
		},
		"composite": {
			"массивы", "arrays", "срезы", "slices", "append", "make", "copy",
			"отображения", "map", "maps", "структуры", "structs", "встраивание",
			"embedding", "анонимные поля", "JSON", "html/template", "шаблоны",
			"маршалинг", "marshal", "unmarshal", "json.Encoder", "json.Decoder",
			"omitempty", "range", "len", "cap", "delete", "composite types",
		},
		"structs": {
			"переменные", "variables", "объявления", "declarations", "типы", "types",
			"указатели", "pointers", "new", "область видимости", "scope",
			"пакеты", "packages", "импорт", "import", "инициализация", "init",
			"var", "const", "nil", "zero value", "нулевое значение",
			"присваивание", "assignment", "ключевые слова", "keywords",
		},
	}
	if v, ok := kw[key]; ok {
		return v
	}
	return []string{}
}
