package apperrorsx

import (
	"strconv"
	"strings"

	"github.com/gofiber/fiber/v2"

	"wucher/internal/transport/http/jsonapi"
)

func Write(c *fiber.Ctx, e *AppError) error {
	if e == nil {
		e = New(ErrInternal)
	}
	if e.Status == 0 {
		e.Status = fiber.StatusInternalServerError
	}
	if e.Title == "" {
		e.Title = defaultTitle(e.Status)
	}
	if detail := publicLogDetail(e.Message, e.Cause, e.Title); detail != "" {
		c.Locals(ContextKeyHTTPErrorDetail, detail)
	}

	obj := jsonapi.ErrorObject{
		Status:    strconv.Itoa(e.Status),
		Code:      e.Code,
		ErrorCode: e.ErrorCode,
		Title:     e.Title,
		Detail:    PublicDetail(e.Status),
		Source:    e.Source,
	}
	return jsonapi.WriteErrors(c, e.Status, []jsonapi.ErrorObject{obj})
}

func publicLogDetail(message string, cause error, fallback string) string {
	if cause != nil {
		if trimmed := strings.TrimSpace(cause.Error()); trimmed != "" {
			return trimmed
		}
	}
	if trimmed := strings.TrimSpace(message); trimmed != "" {
		return trimmed
	}
	return strings.TrimSpace(fallback)
}

func defaultTitle(status int) string {
	switch status {
	case fiber.StatusBadRequest:
		return "Bad Request"
	case fiber.StatusUnauthorized:
		return "Unauthorized"
	case fiber.StatusForbidden:
		return "Forbidden"
	case fiber.StatusNotFound:
		return "Not found"
	case fiber.StatusConflict:
		return "Conflict"
	case fiber.StatusUnprocessableEntity:
		return "Validation error"
	case fiber.StatusTooManyRequests:
		return "Too many requests"
	default:
		return "Internal server error"
	}
}
