package storage

import (
	"context"
	"time"

	"github.com/tech/sendico/gateway/tgsettle/storage/model"
	"github.com/tech/sendico/pkg/merrors"
)

var ErrDuplicate = merrors.DataConflict("payment gateway storage: duplicate record")

type Repository interface {
	Payments() PaymentsStore
	TelegramConfirmations() TelegramConfirmationsStore
	PendingConfirmations() PendingConfirmationsStore
	TreasuryRequests() TreasuryRequestsStore
	TreasuryTelegramUsers() TreasuryTelegramUsersStore
}

type PaymentsStore interface {
	FindByIdempotencyKey(ctx context.Context, key string) (*model.PaymentRecord, error)
	FindByOperationRef(ctx context.Context, key string) (*model.PaymentRecord, error)
	Upsert(ctx context.Context, record *model.PaymentRecord) error
}

type TelegramConfirmationsStore interface {
	Upsert(ctx context.Context, record *model.TelegramConfirmation) error
}

type PendingConfirmationsStore interface {
	Upsert(ctx context.Context, record *model.PendingConfirmation) error
	FindByRequestID(ctx context.Context, requestID string) (*model.PendingConfirmation, error)
	FindByMessageID(ctx context.Context, messageID string) (*model.PendingConfirmation, error)
	MarkClarified(ctx context.Context, requestID string) error
	AttachMessage(ctx context.Context, requestID string, messageID string) error
	DeleteByRequestID(ctx context.Context, requestID string) error
	ListExpired(ctx context.Context, now time.Time, limit int64) ([]model.PendingConfirmation, error)
}

type TreasuryRequestsStore interface {
	Create(ctx context.Context, record *model.TreasuryRequest) error
	FindByRequestID(ctx context.Context, requestID string) (*model.TreasuryRequest, error)
	FindActiveByLedgerAccountID(ctx context.Context, ledgerAccountID string) (*model.TreasuryRequest, error)
	FindDueByStatus(ctx context.Context, statuses []model.TreasuryRequestStatus, now time.Time, limit int64) ([]model.TreasuryRequest, error)
	ClaimScheduled(ctx context.Context, requestID string) (bool, error)
	Update(ctx context.Context, record *model.TreasuryRequest) error
	ListByAccountAndStatuses(ctx context.Context, ledgerAccountID string, statuses []model.TreasuryRequestStatus, dayStart, dayEnd time.Time) ([]model.TreasuryRequest, error)
}

type TreasuryTelegramUsersStore interface {
	FindByTelegramUserID(ctx context.Context, telegramUserID string) (*model.TreasuryTelegramUser, error)
}
