package dao

import (
	"context"
	"rapidashplugin/entity"

	"go.knocknote.io/rapidash"
	"golang.org/x/xerrors"
)

type World interface {
	Count(context.Context) (int64, error)
	Create(context.Context, *entity.World) error
	Delete(context.Context, *entity.World) error
	DeleteByID(context.Context, uint64) error
	DeleteByIDs(context.Context, []uint64) error
	FindAll(context.Context) (entity.Worlds, error)
	FindByID(context.Context, uint64) (*entity.World, error)
	FindByIDs(context.Context, []uint64) (entity.Worlds, error)
	Update(context.Context, *entity.World) error
	UpdateByID(context.Context, uint64, map[string]interface{}) error
	UpdateByIDs(context.Context, []uint64, map[string]interface{}) error
}

type WorldImpl struct {
	tx *rapidash.Tx
}

func NewWorld(ctx context.Context, tx *rapidash.Tx) World {
	return &WorldImpl{tx: tx}
}

// generated by eevee
func (d *WorldImpl) Count(ctx context.Context) (r int64, e error) {
	builder := rapidash.NewQueryBuilder("worlds")
	count, err := d.tx.CountByQueryBuilderContext(ctx, builder)
	if err != nil {
		return 0, xerrors.Errorf("failed to Count: %w", err)
	}
	return int64(count), nil
}

// generated by eevee
func (d *WorldImpl) Create(ctx context.Context, value *entity.World) (e error) {
	id, err := d.tx.CreateByTableContext(ctx, "worlds", value)
	if err != nil {
		return xerrors.Errorf("failed to Create: %w", err)
	}
	value.ID = uint64(id)
	return nil
}

// generated by eevee
func (d *WorldImpl) Delete(ctx context.Context, value *entity.World) (e error) {
	builder := rapidash.NewQueryBuilder("worlds").Eq("id", value.ID)
	if err := d.tx.DeleteByQueryBuilderContext(ctx, builder); err != nil {
		return xerrors.Errorf("failed to Delete: %w", err)
	}
	return nil
}

// generated by eevee
func (d *WorldImpl) DeleteByID(ctx context.Context, a0 uint64) (e error) {
	builder := rapidash.NewQueryBuilder("worlds").Eq("id", a0)
	if err := d.tx.DeleteByQueryBuilderContext(ctx, builder); err != nil {
		return xerrors.Errorf("failed to Delete: %w", err)
	}
	return nil
}

// generated by eevee
func (d *WorldImpl) DeleteByIDs(ctx context.Context, a0 []uint64) (e error) {
	builder := rapidash.NewQueryBuilder("worlds").In("id", a0)
	if err := d.tx.DeleteByQueryBuilderContext(ctx, builder); err != nil {
		return xerrors.Errorf("failed to Delete: %w", err)
	}
	return nil
}

// generated by eevee
func (d *WorldImpl) FindAll(ctx context.Context) (r entity.Worlds, e error) {
	values := entity.Worlds{}
	if err := d.tx.FindAllByTable("worlds", &values); err != nil {
		return values, xerrors.Errorf("failed to FindAll %w", err)
	}
	return values, nil
}

// generated by eevee
func (d *WorldImpl) FindByID(ctx context.Context, a0 uint64) (r *entity.World, e error) {
	builder := rapidash.NewQueryBuilder("worlds").Eq("id", a0)
	var value entity.World
	if err := d.tx.FindByQueryBuilderContext(ctx, builder, &value); err != nil {
		return nil, xerrors.Errorf("failed to Find: %w", err)
	}
	return &value, nil
}

// generated by eevee
func (d *WorldImpl) FindByIDs(ctx context.Context, a0 []uint64) (r entity.Worlds, e error) {
	builder := rapidash.NewQueryBuilder("worlds").In("id", a0)
	values := entity.Worlds{}
	if err := d.tx.FindByQueryBuilderContext(ctx, builder, &values); err != nil {
		return nil, xerrors.Errorf("failed to Find: %w", err)
	}
	return values, nil
}

// generated by eevee
func (d *WorldImpl) Update(ctx context.Context, value *entity.World) (e error) {
	updateMap := map[string]interface{}{"name": value.Name}
	builder := rapidash.NewQueryBuilder("worlds").Eq("id", value.ID)
	if err := d.tx.UpdateByQueryBuilderContext(ctx, builder, updateMap); err != nil {
		return xerrors.Errorf("failed to Update: %w", err)
	}
	return nil
}

// generated by eevee
func (d *WorldImpl) UpdateByID(ctx context.Context, a0 uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("worlds").Eq("id", a0)
	if err := d.tx.UpdateByQueryBuilderContext(ctx, builder, updateMap); err != nil {
		return xerrors.Errorf("failed to Update: %w", err)
	}
	return nil
}

// generated by eevee
func (d *WorldImpl) UpdateByIDs(ctx context.Context, a0 []uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("worlds").In("id", a0)
	if err := d.tx.UpdateByQueryBuilderContext(ctx, builder, updateMap); err != nil {
		return xerrors.Errorf("failed to Update: %w", err)
	}
	return nil
}
