// Code generated by candi v1.0.12.

package repository

import (
	"context"
	"time"

	shareddomain "monorepo/services/user-service/pkg/shared/domain"

	"github.com/google/uuid"
	"gorm.io/gorm"
	"pkg.agungdp.dev/candi/candishared"
	"pkg.agungdp.dev/candi/tracer"
)

type memberRepoSQL struct {
	readDB, writeDB *gorm.DB
}

// NewMemberRepoSQL mongo repo constructor
func NewMemberRepoSQL(readDB, writeDB *gorm.DB) MemberRepository {
	return &memberRepoSQL{
		readDB, writeDB,
	}
}

func (r *memberRepoSQL) FetchAll(ctx context.Context, filter *candishared.Filter) (data []shareddomain.Member, err error) {
	trace := tracer.StartTrace(ctx, "MemberRepoSQL:FetchAll")
	defer func() { trace.SetError(err); trace.Finish() }()

	if filter.OrderBy == "" {
		filter.OrderBy = "modified_at"
	}

	err = r.readDB.
		Order(filter.OrderBy + " " + filter.Sort).
		Limit(filter.Limit).Offset(filter.Offset).
		Find(&data).Error
	return
}

func (r *memberRepoSQL) Count(ctx context.Context, filter *candishared.Filter) (count int) {
	trace := tracer.StartTrace(ctx, "MemberRepoSQL:Count")
	defer trace.Finish()

	var total int64
	r.readDB.Model(&shareddomain.Member{}).Count(&total)
	count = int(total)
	return
}

func (r *memberRepoSQL) Find(ctx context.Context, data *shareddomain.Member) (err error) {
	trace := tracer.StartTrace(ctx, "MemberRepoSQL:Find")
	defer func() { trace.SetError(err); trace.Finish() }()

	return r.readDB.First(data).Error
}

func (r *memberRepoSQL) Save(ctx context.Context, data *shareddomain.Member) (err error) {
	trace := tracer.StartTrace(ctx, "MemberRepoSQL:Save")
	defer func() { trace.SetError(err); trace.Finish() }()
	tracer.Log(ctx, "data", data)

	data.ModifiedAt = time.Now()
	if data.CreatedAt.IsZero() {
		data.CreatedAt = time.Now()
	}

	if data.ID == "" {
		data.ID = uuid.NewString()
		err = r.writeDB.Create(data).Error
	} else {
		err = r.writeDB.Save(data).Error
	}
	return
}

func (r *memberRepoSQL) Delete(ctx context.Context, id string) (err error) {
	trace := tracer.StartTrace(ctx, "MemberRepoSQL:Save")
	defer func() { trace.SetError(err); trace.Finish() }()

	return r.writeDB.Delete(&shareddomain.Member{ID: id}).Error
}
