// Package httperr defines the standard JSON error envelope shared by every
// backend HTTP middleware and handler.
//
// The envelope shape is fixed by `backend/openapi.yaml` (`ErrorResponse`) and
// must remain identical across the public, user, admin, and internal route
// groups so that callers can parse failures uniformly.
package httperr

import (
	"github.com/gin-gonic/gin"
)

// Error code values that appear in the JSON envelope `error.code` field. They
// are documented in `backend/openapi.yaml` and form the closed set of stable
// machine-readable failure markers.
const (
	CodeNotImplemented     = "not_implemented"
	CodeInvalidRequest     = "invalid_request"
	CodeUnauthorized       = "unauthorized"
	CodeForbidden          = "forbidden"
	CodeNotFound           = "not_found"
	CodeConflict           = "conflict"
	CodeMethodNotAllowed   = "method_not_allowed"
	CodeInternalError      = "internal_error"
	CodeServiceUnavailable = "service_unavailable"

	// CodeTurnAlreadyClosed marks a user-games command or order rejection
	// caused by the backend's turn-cutoff guard: the request arrived
	// after the active turn started generating (runtime status
	// `generation_in_progress` / `generation_failed` / `engine_unreachable`)
	// and the engine no longer accepts writes for the closing turn. The
	// caller is expected to wait for the next `game.turn.ready` push and
	// resubmit against the new turn.
	CodeTurnAlreadyClosed = "turn_already_closed"

	// CodeGamePaused marks a user-games command or order rejection caused
	// by the lobby-side game lifecycle: the game is in `paused`,
	// `finished`, or any other status that does not accept writes. The
	// caller is expected to wait for the game to resume before
	// resubmitting.
	CodeGamePaused = "game_paused"
)

// Body stores the inner `error` object of the standard envelope.
type Body struct {
	// Code is the stable machine-readable failure marker.
	Code string `json:"code"`

	// Message is the human-readable client-safe failure description.
	Message string `json:"message"`
}

// Response wraps Body in the documented `{"error":{...}}` shape.
type Response struct {
	Error Body `json:"error"`
}

// Abort writes the standard JSON error envelope with statusCode and aborts the
// gin handler chain. It is the single helper every middleware and handler must
// use to emit a failure response.
func Abort(c *gin.Context, statusCode int, code, message string) {
	c.AbortWithStatusJSON(statusCode, Response{
		Error: Body{
			Code:    code,
			Message: message,
		},
	})
}
