package repo

import (
	"context"

	auditent "github.com/tidbcloud/devops/entity/audit"
	"github.com/tidbcloud/devops/entity/validation"
	"github.com/tidbcloud/devops/pkg/infra/utils/repoopt"
	"github.com/tidbcloud/devops/pkg/service/audit/repo/cvt"

	"github.com/tidbcloud/pkgv2/db"
)

func WithType(typ auditent.AuditLogType) repoopt.Option {
	return &repoopt.Filter[auditent.AuditLogType]{
		Column: "type",
		Value:  &typ,
	}
}

func InObjectIDs(objectIDs []string) repoopt.Option {
	return &repoopt.Filter[string]{
		Column: "object_id",
		Values: objectIDs,
	}
}

func WithPager(page, perPage int, defaultOrder bool) repoopt.Option {
	pager := &repoopt.Pager{
		Page:    page,
		PerPage: perPage,
	}
	if !defaultOrder {
		return pager
	}

	order := &repoopt.Order{
		Column: "operate_at",
		Desc:   true,
	}
	return repoopt.Aggregate(pager, order)
}

type AuditLogRepo interface {
	Create(ctx context.Context, adtLog *auditent.AuditLog) error
	List(ctx context.Context, opts ...repoopt.Option) ([]*auditent.AuditLog, error)
	Count(ctx context.Context, opts ...repoopt.Option) (int64, error)
}

func NewAuditLogRepo(dbp db.Provider) AuditLogRepo {
	d := &driver{
		cvter:      cvt.NewConverter(),
		dbProvider: dbp,
	}

	return &repo{
		driver: d,
	}
}

type repo struct {
	driver Driver
}

func (r *repo) Create(ctx context.Context, adtLog *auditent.AuditLog) error {
	err := validation.AuditLog.AuditLog(adtLog)
	if err != nil {
		return err
	}

	return r.driver.Create(ctx, adtLog)
}

func (r *repo) List(ctx context.Context, opts ...repoopt.Option) ([]*auditent.AuditLog, error) {
	return r.driver.Query(ctx, opts...)
}

func (r *repo) Count(ctx context.Context, opts ...repoopt.Option) (int64, error) {
	return r.driver.Count(ctx, opts...)
}
