package api

import (
	"encoding/json"
	"strings"
)

type reportAttachmentJSON struct {
	ID       string `json:"id"`
	URL      string `json:"url"`
	Name     string `json:"name"`
	MimeType string `json:"mimeType"`
	Size     int64  `json:"size"`
}

func reportAttachmentsFromBody(body string) []reportAttachmentJSON {
	body = strings.TrimSpace(body)
	if body == "" || !strings.HasPrefix(body, "{") {
		return nil
	}
	var root map[string]json.RawMessage
	if err := json.Unmarshal([]byte(body), &root); err != nil {
		return nil
	}
	raw, ok := root["attachments"]
	if !ok || len(raw) == 0 {
		return nil
	}
	var out []reportAttachmentJSON
	if err := json.Unmarshal(raw, &out); err != nil {
		return nil
	}
	return out
}

func reportBodyWithAttachments(body string, attachments []reportAttachmentJSON) (string, error) {
	body = strings.TrimSpace(body)
	var root map[string]any
	if body == "" || !strings.HasPrefix(body, "{") {
		return body, nil
	}
	if err := json.Unmarshal([]byte(body), &root); err != nil {
		return body, err
	}
	if len(attachments) == 0 {
		delete(root, "attachments")
	} else {
		root["attachments"] = attachments
	}
	b, err := json.Marshal(root)
	if err != nil {
		return body, err
	}
	return string(b), nil
}

func reportAttachmentCount(body string) int {
	return len(reportAttachmentsFromBody(body))
}

// mergeReportBodyPreserveAttachments keeps existing attachments when a PATCH body omits the attachments field.
func mergeReportBodyPreserveAttachments(oldBody, newBody string) (string, error) {
	newBody = strings.TrimSpace(newBody)
	if newBody == "" || !strings.HasPrefix(newBody, "{") {
		return newBody, nil
	}
	var root map[string]json.RawMessage
	if err := json.Unmarshal([]byte(newBody), &root); err != nil {
		return newBody, err
	}
	if _, has := root["attachments"]; has {
		return newBody, nil
	}
	oldAtt := reportAttachmentsFromBody(oldBody)
	if len(oldAtt) == 0 {
		return newBody, nil
	}
	return reportBodyWithAttachments(newBody, oldAtt)
}
