package srequest

import (
	"strings"

	"github.com/tech/sendico/pkg/ledgerconv"
	"github.com/tech/sendico/pkg/merrors"
	"github.com/tech/sendico/pkg/model"
	"github.com/tech/sendico/pkg/model/account_role"
	"go.mongodb.org/mongo-driver/v2/bson"
)

type LedgerAccountType string

const (
	LedgerAccountTypeUnspecified LedgerAccountType = "unspecified"
	LedgerAccountTypeAsset       LedgerAccountType = "asset"
	LedgerAccountTypeLiability   LedgerAccountType = "liability"
	LedgerAccountTypeRevenue     LedgerAccountType = "revenue"
	LedgerAccountTypeExpense     LedgerAccountType = "expense"
)

type LedgerAccountStatus string

const (
	LedgerAccountStatusUnspecified LedgerAccountStatus = "unspecified"
	LedgerAccountStatusActive      LedgerAccountStatus = "active"
	LedgerAccountStatusFrozen      LedgerAccountStatus = "frozen"
)

type CreateLedgerAccount struct {
	AccountType   LedgerAccountType        `json:"accountType"`
	Currency      string                   `json:"currency"`
	AllowNegative bool                     `json:"allowNegative,omitempty"`
	Role          account_role.AccountRole `json:"role"`
	Describable   model.Describable        `json:"describable"`
	OwnerRef      *bson.ObjectID           `json:"ownerRef,omitempty"`
	Metadata      map[string]string        `json:"metadata,omitempty"`
}

func (r *CreateLedgerAccount) Validate() error {
	if strings.TrimSpace(r.Currency) == "" {
		return merrors.InvalidArgument("currency is required", "currency")
	}
	if strings.TrimSpace(string(r.AccountType)) == "" || strings.EqualFold(string(r.AccountType), string(LedgerAccountTypeUnspecified)) {
		return merrors.InvalidArgument("accountType is required", "accountType")
	}
	if role := strings.TrimSpace(string(r.Role)); role != "" {
		if _, ok := ledgerconv.ParseAccountRole(role); !ok || ledgerconv.IsAccountRoleUnspecified(role) {
			return merrors.InvalidArgument("role is invalid", "role")
		}
	}
	return nil
}
