package encoders

import (
	"bytes"
	"fmt"
	"strings"

	"git.max-richter.dev/max/marka/template"
)

func RenderList(value any, block template.Block) (string, error) {
	list, ok := value.([]any)
	if !ok {
		return "", fmt.Errorf("expected list for path '%s', got %T", block.Path, value)
	}

	var renderedItems []string
	// Compile the list template for each item
	listBlocks, err := template.CompileTemplate(block.ListTemplate)
	if err != nil {
		return "", fmt.Errorf("failed to compile list template for path '%s': %w", block.Path, err)
	}

	for i, item := range list {
		itemMap, isMap := item.(map[string]any)
		if !isMap {
			// If it's not a map, treat it as a simple value for the '.' path
			itemMap = map[string]any{".": item}
		}

		var itemBuffer bytes.Buffer
		for _, lb := range listBlocks {
			if lb.Type == template.MatchingBlock {
				itemBuffer.WriteString(lb.GetContent())
			} else if lb.Type == template.DataBlock {
				// Special handling for @index in list items
				if lb.Path == "@index" {
					itemBuffer.WriteString(fmt.Sprintf("%d", i+1))
					continue
				}
				// Special handling for '.' path when item is not a map
				if lb.Path == "." && !isMap {
					itemBuffer.WriteString(fmt.Sprintf("%v", item))
					continue
				}
				renderedItemPart, err := RenderBlock(lb, itemMap)
				if err != nil {
					return "", fmt.Errorf("failed to render list item part for path '%s': %w", lb.Path, err)
				}
				itemBuffer.WriteString(renderedItemPart)
			}
		}
		renderedItems = append(renderedItems, itemBuffer.String())
	}
	return strings.Join(renderedItems, "\n"), nil
}
