package model

import (
	"strings"
	"time"

	"github.com/shopspring/decimal"
	"github.com/tech/sendico/pkg/db/storable"
)

const (
	DocumentRecordsCollection = "document_records"
)

// DocumentType represents document kinds cached in storage.
type DocumentType string

const (
	DocumentTypeUnspecified DocumentType = "DOCUMENT_TYPE_UNSPECIFIED"
	DocumentTypeInvoice     DocumentType = "DOCUMENT_TYPE_INVOICE"
	DocumentTypeAct         DocumentType = "DOCUMENT_TYPE_ACT"
	DocumentTypeReceipt     DocumentType = "DOCUMENT_TYPE_RECEIPT"
)

// ActSnapshot captures the immutable data needed to generate an acceptance act.
type ActSnapshot struct {
	PaymentID        string          `bson:"paymentId"        json:"paymentId"`
	Date             time.Time       `bson:"date"             json:"date"`
	ExecutorFullName string          `bson:"executorFullName" json:"executorFullName"`
	Amount           decimal.Decimal `bson:"amount"           json:"amount"`
	Currency         string          `bson:"currency"         json:"currency"`
}

func (s *ActSnapshot) Normalize() {
	if s == nil {
		return
	}

	s.PaymentID = strings.TrimSpace(s.PaymentID)
	s.ExecutorFullName = strings.TrimSpace(s.ExecutorFullName)
	s.Currency = strings.TrimSpace(s.Currency)
}

// DocumentRecord stores document metadata and cached artefacts for a payment.
type DocumentRecord struct {
	storable.Base `bson:",inline" json:",inline"`

	PaymentRef   string                  `bson:"paymentRef"             json:"paymentRef"`
	Snapshot     ActSnapshot             `bson:"snapshot"               json:"snapshot"`
	StoragePaths map[DocumentType]string `bson:"storagePaths,omitempty" json:"storagePaths,omitempty"`
	Hashes       map[DocumentType]string `bson:"hashes,omitempty"       json:"hashes,omitempty"`
}

func (r *DocumentRecord) Normalize() {
	if r == nil {
		return
	}

	r.PaymentRef = strings.TrimSpace(r.PaymentRef)
	r.Snapshot.Normalize()

	if r.StoragePaths == nil {
		r.StoragePaths = map[DocumentType]string{}
	}

	if r.Hashes == nil {
		r.Hashes = map[DocumentType]string{}
	}
}

// Collection implements storable.Storable.
func (*DocumentRecord) Collection() string {
	return DocumentRecordsCollection
}
