package paymethoddb

import (
	"context"

	"github.com/tech/sendico/pkg/auth"
	"github.com/tech/sendico/pkg/db/policy"
	ri "github.com/tech/sendico/pkg/db/repository/index"
	"github.com/tech/sendico/pkg/mlogger"
	"github.com/tech/sendico/pkg/model"
	"github.com/tech/sendico/pkg/mservice"
	"go.mongodb.org/mongo-driver/mongo"
	"go.uber.org/zap"
)

type PaymentMethodsDB struct {
	auth.ProtectedDBImp[*model.PaymentMethod]
	auth.ArchivableDB[*model.PaymentMethod]
}

func Create(ctx context.Context,
	logger mlogger.Logger,
	enforcer auth.Enforcer,
	pdb policy.DB,
	db *mongo.Database,
) (*PaymentMethodsDB, error) {
	p, err := auth.CreateDBImp[*model.PaymentMethod](ctx, logger, pdb, enforcer, mservice.PaymentMethods, db)
	if err != nil {
		return nil, err
	}

	createEmpty := func() *model.PaymentMethod {
		return &model.PaymentMethod{}
	}

	getArchivable := func(c *model.PaymentMethod) model.Archivable {
		return &c.ArchivableBase
	}

	res := &PaymentMethodsDB{
		ProtectedDBImp: *p,
		ArchivableDB: auth.NewArchivableDB(
			p.DBImp,
			logger,
			p.Enforcer,
			createEmpty,
			getArchivable,
		),
	}

	if err := res.DBImp.Repository.CreateIndex(&ri.Definition{
		Keys: []ri.Key{{Field: "recipientRef", Sort: ri.Asc}},
	}); err != nil {
		res.DBImp.Logger.Error("Failed to create recipientRef index for payment methods", zap.Error(err))
		return nil, err
	}

	return res, nil
}
