package rest

import (
	"encoding/json"
	"errors"
	"fmt"
	"log/slog"
	"net/http"
)

type ErrorType string

const (
	ErrorTypeUndefinded  = ""
	ErrorTypeValidation  = "VALIDATION"
	ErrorTypeNotFound    = "NOT_FOUND"
	ErrorTypeServerError = "SERVER_ERROR"
)

type Error struct {
	Type    ErrorType `json:"type"`
	Message string    `json:"message"`
	err     error
}

func WrappErr(err error, errorType ErrorType, message string) *Error {
	return &Error{
		Type:    errorType,
		Message: message,
		err:     err,
	}
}

func (e Error) Unwrap() error {
	return e.err
}

func (e Error) Error() string {
	return fmt.Sprintf("%s: %s", e.Message, e.err.Error())
}

func (e Error) StatusCode() int {
	switch e.Type {
	case ErrorTypeValidation:
		return http.StatusBadRequest
	case ErrorTypeNotFound:
		return http.StatusNotFound
	default:
		return http.StatusInternalServerError
	}
}

func SendErr(w http.ResponseWriter, err error) {
	restErr := &Error{}

	if !errors.As(err, &restErr) {
		slog.Error("internal server error", "err", err)
		restErr = &Error{
			Type: ErrorTypeServerError,
		}
	}

	w.WriteHeader(restErr.StatusCode())
	w.Header().Add("Content-Type", "application/json")
	err = json.NewEncoder(w).Encode(restErr)

	slog.Error("could not send error", "err", err)
}
