package errors

import (
	"fmt"
	"rpirelay/internal/response"
)

var (
	ErrDataFormat    = New(response.RespDataFormat)
	ErrUnauthorized  = New(response.RespUnauthorized)
	ErrNotFound      = New(response.RespNotFound)
	ErrInternalError = New(response.RespInternalError)
	ErrForbidden     = New(response.RespForbidden)
)

type APIError struct {
	code    *response.MessageCode
	status  response.RespType
	message string
	err     error
}

func (e *APIError) Error() string {
	s := fmt.Sprintf("Status: %s, Message: %s", e.status, e.message)
	if e.code != nil {
		c, m := response.GetCodeMessage(*e.code)
		s = fmt.Sprintf("%s, Code: %d, CodeMessage: %s", s, c, m)
	}
	if e.err != nil {
		s += fmt.Sprintf("\n%+v", e.err)
	}
	return s
}

func (e *APIError) SetCode(code response.MessageCode) *APIError {
	e = &APIError{
		status:  e.status,
		code:    &code,
		message: e.message,
		err:     e.err,
	}
	return e
}

func (e *APIError) SetMessage(s string) *APIError {
	e = &APIError{
		status:  e.status,
		code:    e.code,
		message: s,
		err:     e.err,
	}

	return e
}

func (e *APIError) SetErr(err error) *APIError {
	e = &APIError{
		status:  e.status,
		code:    e.code,
		message: e.message,
		err:     err,
	}

	return e
}

func (e *APIError) Code() *response.MessageCode { return e.code }
func (e *APIError) Status() response.RespType   { return e.status }

func New(status response.RespType, code ...response.MessageCode) *APIError {
	e := &APIError{
		status: status,
	}

	if len(code) > 0 {
		e.code = &code[0]
	}
	return e
}
