package automation

import (
	"errors"
	"net/http"
)

var (
	ErrUnauthorized    = errors.New("unauthorized")
	ErrInvalidArgument = errors.New("invalid argument")
	ErrForbidden       = errors.New("forbidden")
	ErrNotFound        = errors.New("not found")
	ErrConflict        = errors.New("conflict")
)

type domainError struct {
	kind    error
	msg     string
	code    string
	details any
}

func (e domainError) Error() string { return e.msg }
func (e domainError) Unwrap() error { return e.kind }

func unauthorized(message string) error { return domainError{kind: ErrUnauthorized, msg: message} }
func invalidArgument(message string) error {
	return domainError{kind: ErrInvalidArgument, msg: message}
}
func forbidden(message string) error { return domainError{kind: ErrForbidden, msg: message} }
func notFound(message string) error  { return domainError{kind: ErrNotFound, msg: message} }
func conflict(message string) error  { return domainError{kind: ErrConflict, msg: message} }
func codedUnauthorized(code, message string) error {
	return domainError{kind: ErrUnauthorized, msg: message, code: code}
}
func codedForbidden(code, message string) error {
	return domainError{kind: ErrForbidden, msg: message, code: code}
}
func codedNotFound(code, message string) error {
	return domainError{kind: ErrNotFound, msg: message, code: code}
}
func codedInvalidArgument(code, message string) error {
	return domainError{kind: ErrInvalidArgument, msg: message, code: code}
}
func codedInvalidArgumentDetails(code, message string, details any) error {
	return domainError{kind: ErrInvalidArgument, msg: message, code: code, details: details}
}
func codedConflict(code, message string, details any) error {
	return domainError{kind: ErrConflict, msg: message, code: code, details: details}
}

func Code(err error) string {
	var domain domainError
	if errors.As(err, &domain) {
		return domain.code
	}
	return ""
}

func Details(err error) any {
	var domain domainError
	if errors.As(err, &domain) {
		return domain.details
	}
	return nil
}

// HTTPStatus maps service-domain errors to HTTP status codes.
func HTTPStatus(err error) int {
	switch {
	case errors.Is(err, ErrUnauthorized):
		return http.StatusUnauthorized
	case errors.Is(err, ErrInvalidArgument):
		return http.StatusBadRequest
	case errors.Is(err, ErrForbidden):
		return http.StatusForbidden
	case errors.Is(err, ErrNotFound):
		return http.StatusNotFound
	case errors.Is(err, ErrConflict):
		return http.StatusConflict
	default:
		return http.StatusInternalServerError
	}
}
