package commands

import (
	"fmt"
	"strings"

	"c65gm/internal/compiler"
	"c65gm/internal/preproc"
)

// MacroCommand handles macro invocations
// Syntax: @macroname(arg1, arg2, ...)
type MacroCommand struct {
	macroName      string
	args           []string
	pragmaSetIndex int
}

func (c *MacroCommand) WillHandle(line preproc.Line) bool {
	trimmed := strings.TrimSpace(line.Text)
	return strings.HasPrefix(trimmed, "@")
}

func (c *MacroCommand) Interpret(line preproc.Line, _ *compiler.CompilerContext) error {
	trimmed := strings.TrimSpace(line.Text)

	name, args, err := compiler.ParseMacroInvocation(trimmed)
	if err != nil {
		return err
	}

	c.macroName = name
	c.args = args
	c.pragmaSetIndex = line.PragmaSetIndex
	return nil
}

func (c *MacroCommand) Generate(ctx *compiler.CompilerContext) ([]string, error) {
	macroOutput, err := compiler.ExecuteMacro(c.macroName, c.args, ctx, c.pragmaSetIndex)
	if err != nil {
		return nil, fmt.Errorf("macro %s: %w", c.macroName, err)
	}

	// Return output with end comment
	result := macroOutput
	result = append(result, fmt.Sprintf("; end @%s", c.macroName))
	return result, nil
}

func (c *MacroCommand) GetClass() compiler.CmdClass { return compiler.CmdBoundary }
func (c *MacroCommand) GetName() string              { return "MACRO" }
