package repository

import (
	"context"
	"time"

	libmongo "gateway/internal/library/mongo"
	authdomain "gateway/internal/model/auth/domain"
	"gateway/internal/model/auth/domain/entity"
	domrepo "gateway/internal/model/auth/domain/repository"

	"go.mongodb.org/mongo-driver/v2/bson"
	mongodriver "go.mongodb.org/mongo-driver/v2/mongo"
)

// RegistrationMetaRepositoryParam configures the Mongo registration metadata repository.
type RegistrationMetaRepositoryParam struct {
	Conf *libmongo.Conf
}

type registrationMetaRepository struct {
	db libmongo.DocumentDBUseCase
}

// NewRegistrationMetaRepository creates a Mongo-backed RegistrationMetaRepository.
func NewRegistrationMetaRepository(param RegistrationMetaRepositoryParam) domrepo.RegistrationMetaRepository {
	documentDB, err := libmongo.NewDocumentDB(param.Conf, entity.RegistrationMetadata{}.CollectionName())
	if err != nil {
		panic(err)
	}
	return &registrationMetaRepository{db: documentDB}
}

func (r *registrationMetaRepository) Insert(ctx context.Context, rec *entity.RegistrationMetadata) error {
	now := time.Now().UTC().UnixMilli()
	if rec.ID.IsZero() {
		rec.ID = bson.NewObjectID()
	}
	if rec.CreateAt == 0 {
		rec.CreateAt = now
	}
	if rec.OccurredAt == 0 {
		rec.OccurredAt = now
	}
	_, err := r.db.GetClient().InsertOne(ctx, rec)
	if err != nil {
		if mongodriver.IsDuplicateKeyError(err) {
			return authdomain.ErrDuplicateRegistrationMeta
		}
		return err
	}
	return nil
}

// Index20260521002UP ensures registration_metadata collection indexes exist.
func (r *registrationMetaRepository) Index20260521002UP(ctx context.Context) error {
	return r.db.PopulateMultiIndex(ctx,
		[]string{authdomain.BSONFieldTenantID, authdomain.BSONFieldUID},
		[]int32{1, 1},
		true,
	)
}

var _ domrepo.RegistrationMetaRepository = (*registrationMetaRepository)(nil)
