package services

import (
	"os"
	"path/filepath"
	"strings"

	"sproutclaw-web/internal/models"
)

// builtinCommands are the slash commands the WebUI handles natively.
var builtinCommands = []models.SlashCommand{
	{Name: "new", Description: "开启新会话", Source: "builtin"},
	{Name: "compact", Description: "压缩会话历史", Source: "builtin"},
	{Name: "reload", Description: "重载配置", Source: "builtin"},
	{Name: "clone", Description: "克隆当前会话", Source: "builtin"},
	{Name: "name", Description: "重命名当前会话", Source: "builtin"},
	{Name: "model", Description: "切换模型", Source: "builtin"},
	{Name: "session", Description: "显示会话统计", Source: "builtin"},
	{Name: "export", Description: "导出为 HTML", Source: "builtin"},
	{Name: "copy", Description: "复制最后一条助手消息", Source: "builtin"},
	{Name: "webui", Description: "WebUI 控制", Source: "builtin"},
}

// ListSlashCommands aggregates all slash commands visible in the WebUI.
func ListSlashCommands(agentDir string) []models.SlashCommand {
	cmds := make([]models.SlashCommand, len(builtinCommands))
	copy(cmds, builtinCommands)

	// scan skills dir for SKILL.md files
	skillsDir := filepath.Join(agentDir, "skills")
	cmds = append(cmds, scanSkillCommands(skillsDir)...)

	return cmds
}

func scanSkillCommands(skillsDir string) []models.SlashCommand {
	entries, err := os.ReadDir(skillsDir)
	if err != nil {
		return nil
	}
	var cmds []models.SlashCommand
	for _, e := range entries {
		if !e.IsDir() {
			continue
		}
		skillMd := filepath.Join(skillsDir, e.Name(), "SKILL.md")
		name, desc := parseSkillMD(skillMd)
		if name == "" {
			name = e.Name()
		}
		cmds = append(cmds, models.SlashCommand{
			Name:        name,
			Description: desc,
			Source:      "skill",
		})
	}
	return cmds
}

func parseSkillMD(path string) (name, desc string) {
	data, err := os.ReadFile(path)
	if err != nil {
		return "", ""
	}
	content := string(data)
	// parse frontmatter between --- delimiters
	if !strings.HasPrefix(content, "---") {
		return "", ""
	}
	parts := strings.SplitN(content, "---", 3)
	if len(parts) < 3 {
		return "", ""
	}
	fm := parts[1]
	for _, line := range strings.Split(fm, "\n") {
		kv := strings.SplitN(line, ":", 2)
		if len(kv) != 2 {
			continue
		}
		k := strings.TrimSpace(kv[0])
		v := strings.TrimSpace(kv[1])
		switch k {
		case "name":
			name = v
		case "description":
			desc = v
		}
	}
	return name, desc
}
