package mux

import (
	"fmt"
	"sort"
	"strconv"

	"git.mgmcomp.net/thisnthat/discordgo"
)

func (r *Router) helpCommandHandler(s *discordgo.Session, m *discordgo.Message, ctx *Context) {
	displayPrefix := ""

	switch ctx.Method {
	case DirectMethod:
		displayPrefix = ""
	case PrefixMethod:
		displayPrefix = r.prefix
	case MentionMethod:
		displayPrefix = fmt.Sprintf("@%s ", s.State.User.Username)
	}

	maxDisplayLen := 0
	cmdmap := make(map[string]*route)
	catMap := make(map[string][]string)
	var cats []string

	var isAdmin = r.isAdminRoute(s, m, ctx)

	for _, v := range r.categories {
		keys := make([]string, 0, len(r.routes))
		for _, route := range r.routes {
			// If the route is hidde, do not add it to the help list
			if route.Hidden {
				continue
			}

			if route.Admin && !isAdmin {
				continue
			}

			if route.CategoryID == v.ID {
				l := len(route.Usage) // TODO: Add the +args part :)
				if l > maxDisplayLen {
					maxDisplayLen = l
				}
				cmdmap[route.Name] = route
				keys = append(keys, route.Name)
			}
		}

		if len(keys) > 0 {
			sort.Strings(keys)
			catMap[v.Description] = keys
			cats = append(cats, v.Description)
		}
	}

	keys := make([]string, 0, len(r.routes))
	for _, route := range r.routes {
		if route.CategoryID == 0 {
			if route.Admin && !isAdmin {
				continue
			}

			l := len(route.Usage) // TODO: Add the +args part :)
			if l > maxDisplayLen {
				maxDisplayLen = l
			}
			cmdmap[route.Name] = route

			keys = append(keys, route.Name)
		}
	}

	v, ok := cmdmap["help"]
	if ok {
		keys = append([]string{v.Name}, keys...)
	}

	v, ok = cmdmap["about"]
	if ok {
		keys = append([]string{v.Name}, keys...)
	}

	if len(keys) > 0 {
		sort.Strings(keys)
		catMap[""] = keys
		cats = append(cats, "")
	}

	maxDisplayLen = maxDisplayLen + 3

	// TODO: Learn more link needs to be configurable
	innerResp := ""

	// Add sorted result to help msg
	for _, catKey := range cats {
		if catKey != "" {
			innerResp += fmt.Sprintf("\n%s\n", catKey)
		} else {
			innerResp += "\n\n"
		}

		routes := catMap[catKey]
		for _, routeKey := range routes {
			route := cmdmap[routeKey]
			innerResp += fmt.Sprintf("%s%-"+strconv.Itoa(maxDisplayLen)+"s # %s\n", displayPrefix, route.Usage, route.Description)
		}
	}

	if innerResp == "" {
		return
	}

	resp := "```autoit\n" + innerResp + "```\n"
	s.ChannelMessageSend(m.ChannelID, resp)
}