package mux

import (
	"fmt"
	"regexp"
	"strings"

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

// OnMessageCreate is a DiscordGo Event Handler function.  This must be
// registered using the DiscordGo.Session.AddHandler function.  This function
// will receive all Discord messages and parse them for matches to registered
// routes.
func (r *Router) OnMessageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	var err error

	// Ignore all messages created by the Bot account itself
	if m.Author.ID == s.State.User.ID {
		return
	}

	// Start building the command context
	ctx := &Context{
		Content: strings.TrimSpace(m.Content),
	}

	var channel *discordgo.Channel
	channel, err = s.State.Channel(m.ChannelID)
	if err != nil {
		channel, err = s.Channel(m.ChannelID)
		if err != nil {
		} else {
			err = s.State.ChannelAdd(channel)
			if err != nil {
			}
		}
	}

	var isDirectMessage bool // The message was received in a direct message
	var isCommand bool       // The message is intended as a command to the bot

	if channel != nil {
		if channel.Type == discordgo.ChannelTypeDM {
			isDirectMessage = true
			isCommand = true
			ctx.Method = DirectMethod
		}
	}

	if !isDirectMessage {
		reg := regexp.MustCompile(fmt.Sprintf("<@!?(%s)>", s.State.User.ID))

		for _, mention := range m.Mentions {
			if mention.ID == s.State.User.ID {
				// Was the @mention the first part of the string?
				if reg.FindStringIndex(ctx.Content)[0] == 0 {
					isCommand = true
					ctx.Method = MentionMethod
				}

				ctx.Content = reg.ReplaceAllString(ctx.Content, "")
			}
		}

		// Check to see if the context string starts with the command prefix
		if len(r.prefix) > 0 {
			// If the content start with the command prefix, then this is intended as a command
			if strings.HasPrefix(ctx.Content, r.prefix) {
				isCommand = true
				ctx.Method = PrefixMethod
				// Strip off the command prefix
				ctx.Content = strings.TrimPrefix(ctx.Content, r.prefix)
			}
		}
	}

	// If this is not a command do nothing
	if !isCommand {
		return
	}

	route, fields, args := r.findRoute(ctx.Content, MessageRoute)
	if route != nil {
		ctx.Fields = fields
		ctx.Args = args
		route.Run(s, m.Message, ctx)
		return
	}

	r.helpRoute.Run(s, m.Message, ctx)
}