package command

import (
	"fmt"
	"himbot/lib"
	"strings"

	"github.com/bwmarrin/discordgo"
)

func BalanceGetCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
	user, err := lib.GetUser(i)
	if err != nil {
		return "", err
	}

	balance, err := lib.GetBalance(user.ID, i.GuildID)
	if err != nil {
		return "", err
	}

	return fmt.Sprintf("💸 You have %d Himbucks! 💸", balance), nil
}

func LeaderboardCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
	entries, err := lib.GetLeaderboard(i.GuildID, 10)
	if err != nil {
		return "", err
	}

	if len(entries) == 0 {
		return "No himbucks earned yet!", nil
	}

	var sb strings.Builder
	sb.WriteString("🏆 Himbucks Leaderboard 🏆\n\n")
	for idx, entry := range entries {
		sb.WriteString(fmt.Sprintf("%d. %s: %d himbucks\n", idx+1, entry.Username, entry.Balance))
	}

	return sb.String(), nil
}

func BalanceSendCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
	options := i.ApplicationCommandData().Options

	// Discord handles the user mention/tag and provides the correct user ID
	var recipientID string
	var amount int

	for _, opt := range options {
		switch opt.Name {
		case "user":
			recipientID = opt.UserValue(nil).ID
		case "amount":
			amount = int(opt.IntValue())
		}
	}

	// Validate amount
	if amount <= 0 {
		return "", fmt.Errorf("amount must be positive")
	}

	// Get sender's info
	sender, err := lib.GetUser(i)
	if err != nil {
		return "", fmt.Errorf("failed to get sender info: %w", err)
	}

	// Don't allow sending to self
	if sender.ID == recipientID {
		return "", fmt.Errorf("you cannot send himbucks to yourself")
	}

	// Get recipient's info
	recipient, err := s.User(recipientID)
	if err != nil {
		return "", fmt.Errorf("failed to get recipient info: %w", err)
	}

	// Send the himbucks
	err = lib.SendBalance(sender.ID, recipientID, i.GuildID, amount)
	if err != nil {
		return "", fmt.Errorf("failed to send himbucks: %w", err)
	}

	return fmt.Sprintf("💸 Successfully sent %d Himbucks to %s! 💸", amount, recipient.Username), nil
}

func GiveCommand(s *discordgo.Session, i *discordgo.InteractionCreate) (string, error) {
	if !isAdmin(i.Member.User.ID) {
		s.InteractionResponseDelete(i.Interaction)

		s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
			Content: "You do not have permission to use this command.",
			Flags:   discordgo.MessageFlagsEphemeral,
		})

		return "", nil
	}

	options := i.ApplicationCommandData().Options
	var recipientID string
	var amount int

	for _, opt := range options {
		switch opt.Name {
		case "user":
			recipientID = opt.UserValue(nil).ID
		case "amount":
			amount = int(opt.IntValue())
		}
	}

	recipient, err := s.User(recipientID)
	if err != nil {
		return "", fmt.Errorf("failed to get recipient info: %w", err)
	}

	_, err = lib.GetOrCreateUserWithGuild(recipientID, recipient.Username, i.GuildID)
	if err != nil {
		return "", fmt.Errorf("failed to initialize recipient profile: %w", err)
	}

	err = lib.GiveHimbucks(recipientID, i.GuildID, amount)
	if err != nil {
		return "", fmt.Errorf("failed to give himbucks: %w", err)
	}

	action := "given to"
	if amount < 0 {
		action = "taken from"
		amount = -amount
	}

	// Delete public "thinking" message
	s.InteractionResponseDelete(i.Interaction)

	// Send ephemeral success message
	s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
		Content: fmt.Sprintf("Successfully %s %s %d Himbucks.", action, recipient.Username, amount),
		Flags:   discordgo.MessageFlagsEphemeral,
	})

	return "", nil
}

func isAdmin(userID string) bool {
	for _, adminID := range lib.AppConfig.AdminIDs {
		if userID == adminID {
			return true
		}
	}
	return false
}
