package layoutownership

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"

	"github.com/nexuscrm/shared/pkg/models"
)

// DecodePageLayoutConfig is the single lossless decoder for PageLayout
// authoring JSON. UseNumber is required because extension values may contain
// decimals whose precision or authored scale cannot survive float64.
func DecodePageLayoutConfig(raw []byte) (models.PageLayout, error) {
	return decodePageLayoutConfig(raw, false)
}

// DecodePageLayoutConfigStrict applies the same lossless numeric and document
// framing contract while also rejecting fields outside the typed PageLayout
// model. AppRelease behavior validation uses this entry point so strictness
// does not require a second, lossy decoder.
func DecodePageLayoutConfigStrict(raw []byte) (models.PageLayout, error) {
	return decodePageLayoutConfig(raw, true)
}

func decodePageLayoutConfig(raw []byte, disallowUnknownFields bool) (models.PageLayout, error) {
	var layout models.PageLayout
	decoder := json.NewDecoder(bytes.NewReader(raw))
	decoder.UseNumber()
	if disallowUnknownFields {
		decoder.DisallowUnknownFields()
	}
	if err := decoder.Decode(&layout); err != nil {
		return layout, err
	}
	if err := decoder.Decode(&struct{}{}); err != io.EOF {
		if err == nil {
			return layout, fmt.Errorf("page layout config contains multiple JSON values")
		}
		return layout, fmt.Errorf("page layout config has trailing data: %w", err)
	}
	return layout, nil
}
