package errs

import (
	"fmt"
	"strings"

	"backend/pkg/library/errs/code"

	"github.com/zeromicro/go-zero/core/logx"
)

type ErrorCode uint32

func (e ErrorCode) ToUint32() uint32 {
	return uint32(e)
}

func ThirdPartyError(scope uint32, ec ErrorCode, s ...string) *LibError {
	return NewError(scope, code.ThirdParty, ec.ToUint32(), fmt.Sprintf("thirty error: %s", strings.Join(s, " ")))
}

func ThirdPartyErrorL(scope uint32, ec ErrorCode,
	l logx.Logger, filed []logx.LogField, s ...string) *LibError {
	e := ThirdPartyError(scope, ec, s...)
	l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())

	return e
}

func DatabaseErrorWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
	return NewError(scope, code.DBError, ec.ToUint32(), strings.Join(s, " "))
}

func DatabaseErrorWithScopeL(scope uint32,
	ec ErrorCode,
	l logx.Logger, filed []logx.LogField, s ...string) *LibError {
	e := DatabaseErrorWithScope(scope, ec, s...)
	l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())

	return e
}

func ResourceNotFoundWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
	return NewError(scope, code.ResourceNotFound, ec.ToUint32(), fmt.Sprintf("resource not found: %s", strings.Join(s, " ")))
}

func ResourceNotFoundWithScopeL(scope uint32, ec ErrorCode,
	l logx.Logger, filed []logx.LogField, s ...string) *LibError {
	e := ResourceNotFoundWithScope(scope, ec, s...)
	l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())

	return e
}

func InvalidRangeWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
	return NewError(scope, code.CatInput, ec.ToUint32(), fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
}

func InvalidRangeWithScopeL(scope uint32, ec ErrorCode,
	l logx.Logger, filed []logx.LogField, s ...string) *LibError {
	e := InvalidRangeWithScope(scope, ec, s...)
	l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())

	return e
}

func InvalidFormatWithScope(scope uint32, s ...string) *LibError {
	return NewError(scope, code.CatInput, code.InvalidFormat, fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
}

func InvalidFormatWithScopeL(scope uint32,
	l logx.Logger, filed []logx.LogField, s ...string) *LibError {
	e := InvalidFormatWithScope(scope, s...)
	l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())

	return e
}

func ForbiddenWithScope(scope uint32, ec ErrorCode, s ...string) *LibError {
	return NewError(scope, code.Forbidden, ec.ToUint32(), fmt.Sprintf("forbidden: %s", strings.Join(s, " ")))
}

func ForbiddenWithScopeL(scope uint32, ec ErrorCode,
	l logx.Logger, filed []logx.LogField, s ...string) *LibError {
	e := ForbiddenWithScope(scope, ec, s...)
	l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())

	return e
}
