// Package renderer provides functions for rendering Marka templates.
package renderer

import (
	"encoding/json"
	"fmt"

	"git.max-richter.dev/max/marka/registry"
	"git.max-richter.dev/max/marka/renderer/encoders"
	"git.max-richter.dev/max/marka/template"
	"git.max-richter.dev/max/marka/validator"
)

func RenderFile(rawJSON []byte) ([]byte, error) {
	// 1) parse json
	var data map[string]any
	if err := json.Unmarshal(rawJSON, &data); err != nil {
		return nil, fmt.Errorf("failed to parse JSON: %w", err)
	}

	// 2) extract type from "_type" Property
	contentType, ok := data["_type"].(string)
	if !ok || contentType == "" {
		return nil, fmt.Errorf("JSON does not contain a valid '_type' property")
	}

	// 3) get the template from the registry
	templateContent, err := registry.GetTemplate(contentType)
	if err != nil {
		return nil, fmt.Errorf("could not get template for type '%s': %w", contentType, err)
	}

	// 4) parse the template with the template package
	compiledTemplate, err := template.CompileTemplate(templateContent)
	if err != nil {
		return nil, fmt.Errorf("failed to compile template for type '%s': %w", contentType, err)
	}

	// 5) validate JSON against schema
	if schemaName, ok := data["_schema"].(string); ok {
		if validationErr := validator.ValidateSchema(data, schemaName); validationErr != nil {
			return nil, fmt.Errorf("failed to validate schema: %w", validationErr)
		}
	}

	// 6) render the template with the blocks
	outputString, err := encoders.Render(data, compiledTemplate)
	if err != nil {
		return nil, fmt.Errorf("failed to render template: %w", err)
	}

	return []byte(outputString), nil
}
