// Package httpresponse provides standard HTTP response types and helpers.
//
// This package implements an envelope pattern for consistent API responses:
//
//	{
//	    "data": {...},         // Present on success
//	    "error": {...},        // Present on error
//	    "meta": {
//	        "request_id": "...",
//	        "trace_id": "...",
//	        "timestamp": "..."
//	    }
//	}
//
// Usage:
//
//	func GetUser(w http.ResponseWriter, r *http.Request) {
//	    user, err := svc.Get(ctx, id)
//	    if err != nil {
//	        httpresponse.NotFound(w, r, "user not found")
//	        return
//	    }
//	    httpresponse.OK(w, r, user)
//	}
package httpresponse

import (
	"net/http"
	"time"

	"{{GO_MODULE}}/pkg/httpcontext"
)

// Response is the standard envelope for all API responses.
type Response struct {
	Data  any    `json:"data,omitempty"`
	Error *Error `json:"error,omitempty"`
	Meta  Meta   `json:"meta"`
}

// Error represents an API error in the response envelope.
type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Details any    `json:"details,omitempty"`
}

// Meta contains response metadata.
type Meta struct {
	RequestID string `json:"request_id,omitempty"`
	TraceID   string `json:"trace_id,omitempty"`
	Timestamp string `json:"timestamp"`
}

// newMeta creates a Meta with current timestamp, request ID, and trace ID from context.
func newMeta(r *http.Request) Meta {
	requestID, _ := httpcontext.GetRequestID(r.Context())
	traceID, _ := httpcontext.GetTraceID(r.Context())
	return Meta{
		RequestID: requestID,
		TraceID:   traceID,
		Timestamp: time.Now().UTC().Format(time.RFC3339),
	}
}

// Error codes for machine-readable error classification.
const (
	CodeBadRequest   = "BAD_REQUEST"
	CodeUnauthorized = "UNAUTHORIZED"
	CodeForbidden    = "FORBIDDEN"
	CodeNotFound     = "NOT_FOUND"
	CodeConflict     = "CONFLICT"
	CodeInternal     = "INTERNAL_ERROR"
	CodeValidation   = "VALIDATION_ERROR"
)
