package middleware

import (
	"system-altrak/pkg/utils"

	"github.com/gofiber/fiber/v2"
	"go.uber.org/zap"
)

func GlobalErrorHandler(c *fiber.Ctx, err error) error {
	code := fiber.StatusInternalServerError
	if e, ok := err.(*fiber.Error); ok {
		code = e.Code
	}

	// Log errors (4xx as Info/Warn, 5xx as Error)
	rid := c.Locals("requestId")
	if code >= 500 {
		utils.Error("Handler Error",
			zap.Error(err),
			zap.Any("requestId", rid),
			zap.String("method", c.Method()),
			zap.String("path", c.Path()),
			zap.Int("status", code),
		)
	} else if code != fiber.StatusNotFound || (c.Path() != "/favicon.ico") {
		// Log 4xx as Info, except for common noise like missing favicon
		utils.Info("Client Error",
			zap.Error(err),
			zap.Any("requestId", rid),
			zap.String("method", c.Method()),
			zap.String("path", c.Path()),
			zap.Int("status", code),
		)
	}

	if code == fiber.StatusNotFound {
		return utils.NotFoundResponse(c, "Halaman")
	}

	// Use appropriate response functions based on status code
	switch code {
	case fiber.StatusUnauthorized:
		return utils.UnauthorizedResponse(c, err.Error())
	case fiber.StatusForbidden:
		return utils.ForbiddenResponse(c, err.Error())
	case fiber.StatusBadRequest:
		return utils.ErrorResponse(c, code, err.Error())
	default:
		return utils.InternalErrorResponse(c, err.Error())
	}
}
