package commands

import (
	"fmt"
	"strings"

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

// FuncCommand handles FUNC declarations
// Syntax:
//
//	FUNC name                              # void function
//	FUNC name ( param1 param2 )            # function with parameters
//	FUNC name ( in:x out:y io:z )          # with direction modifiers
//	FUNC name ( {BYTE temp} out:result )   # with implicit declarations
type FuncCommand struct {
	funcName string
}

func (c *FuncCommand) WillHandle(line preproc.Line) bool {
	params, err := utils.ParseParams(line.Text)
	if err != nil || len(params) == 0 {
		return false
	}
	return strings.ToUpper(params[0]) == "FUNC"
}

func (c *FuncCommand) Interpret(line preproc.Line, ctx *compiler.CompilerContext) error {
	c.funcName = ""

	funcName, err := ctx.FunctionHandler.HandleFuncDecl(line)
	if err != nil {
		return err
	}

	c.funcName = funcName
	return nil
}

func (c *FuncCommand) Generate(_ *compiler.CompilerContext) ([]string, error) {
	if c.funcName == "" {
		return nil, nil // No function name parsed
	}
	// Prepend marker before the function label
	marker := fmt.Sprintf("; @@FUNC_BEGIN %s", c.funcName)
	return []string{marker, c.funcName}, nil
}

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