package dao

import (
	"context"
	"rapidashplugin/entity"

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

type User interface {
	Count(context.Context) (int64, error)
	Create(context.Context, *entity.User) error
	Delete(context.Context, *entity.User) error
	DeleteByGroupID(context.Context, uint64) error
	DeleteByGroupIDs(context.Context, []uint64) error
	DeleteByID(context.Context, uint64) error
	DeleteByIDs(context.Context, []uint64) error
	DeleteByName(context.Context, string) error
	DeleteByNames(context.Context, []string) error
	DeleteBySkillIDAndSkillRank(context.Context, uint64, int) error
	DeleteByWorldIDAndFieldID(context.Context, uint64, uint64) error
	FindAll(context.Context) (entity.Users, error)
	FindByGroupID(context.Context, uint64) (entity.Users, error)
	FindByGroupIDs(context.Context, []uint64) (entity.Users, error)
	FindByID(context.Context, uint64) (*entity.User, error)
	FindByIDs(context.Context, []uint64) (entity.Users, error)
	FindByName(context.Context, string) (*entity.User, error)
	FindByNames(context.Context, []string) (entity.Users, error)
	FindBySkillID(context.Context, uint64) (entity.Users, error)
	FindBySkillIDAndSkillRank(context.Context, uint64, int) (*entity.User, error)
	FindBySkillIDs(context.Context, []uint64) (entity.Users, error)
	FindByWorldID(context.Context, uint64) (entity.Users, error)
	FindByWorldIDAndFieldID(context.Context, uint64, uint64) (entity.Users, error)
	FindByWorldIDs(context.Context, []uint64) (entity.Users, error)
	Update(context.Context, *entity.User) error
	UpdateByGroupID(context.Context, uint64, map[string]interface{}) error
	UpdateByGroupIDs(context.Context, []uint64, map[string]interface{}) error
	UpdateByID(context.Context, uint64, map[string]interface{}) error
	UpdateByIDs(context.Context, []uint64, map[string]interface{}) error
	UpdateByName(context.Context, string, map[string]interface{}) error
	UpdateByNames(context.Context, []string, map[string]interface{}) error
	UpdateBySkillIDAndSkillRank(context.Context, uint64, int, map[string]interface{}) error
	UpdateByWorldIDAndFieldID(context.Context, uint64, uint64, map[string]interface{}) error
}

type UserImpl struct {
	tx *rapidash.Tx
}

func NewUser(ctx context.Context, tx *rapidash.Tx) User {
	return &UserImpl{tx: tx}
}

// generated by eevee
func (d *UserImpl) Count(ctx context.Context) (r int64, e error) {
	builder := rapidash.NewQueryBuilder("users")
	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 *UserImpl) Create(ctx context.Context, value *entity.User) (e error) {
	id, err := d.tx.CreateByTableContext(ctx, "users", value)
	if err != nil {
		return xerrors.Errorf("failed to Create: %w", err)
	}
	value.ID = uint64(id)
	return nil
}

// generated by eevee
func (d *UserImpl) Delete(ctx context.Context, value *entity.User) (e error) {
	builder := rapidash.NewQueryBuilder("users").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 *UserImpl) DeleteByGroupID(ctx context.Context, a0 uint64) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("group_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 *UserImpl) DeleteByGroupIDs(ctx context.Context, a0 []uint64) (e error) {
	builder := rapidash.NewQueryBuilder("users").In("group_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 *UserImpl) DeleteByID(ctx context.Context, a0 uint64) (e error) {
	builder := rapidash.NewQueryBuilder("users").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 *UserImpl) DeleteByIDs(ctx context.Context, a0 []uint64) (e error) {
	builder := rapidash.NewQueryBuilder("users").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 *UserImpl) DeleteByName(ctx context.Context, a0 string) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("name", 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 *UserImpl) DeleteByNames(ctx context.Context, a0 []string) (e error) {
	builder := rapidash.NewQueryBuilder("users").In("name", 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 *UserImpl) DeleteBySkillIDAndSkillRank(ctx context.Context, a0 uint64, a1 int) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("skill_id", a0).Eq("skill_rank", a1)
	if err := d.tx.DeleteByQueryBuilderContext(ctx, builder); err != nil {
		return xerrors.Errorf("failed to Delete: %w", err)
	}
	return nil
}

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

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

// generated by eevee
func (d *UserImpl) FindByGroupID(ctx context.Context, a0 uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("group_id", a0)
	var values entity.Users
	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 *UserImpl) FindByGroupIDs(ctx context.Context, a0 []uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").In("group_id", a0)
	values := entity.Users{}
	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 *UserImpl) FindByID(ctx context.Context, a0 uint64) (r *entity.User, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("id", a0)
	var value entity.User
	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 *UserImpl) FindByIDs(ctx context.Context, a0 []uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").In("id", a0)
	values := entity.Users{}
	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 *UserImpl) FindByName(ctx context.Context, a0 string) (r *entity.User, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("name", a0)
	var value entity.User
	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 *UserImpl) FindByNames(ctx context.Context, a0 []string) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").In("name", a0)
	values := entity.Users{}
	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 *UserImpl) FindBySkillID(ctx context.Context, a0 uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("skill_id", a0)
	var values entity.Users
	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 *UserImpl) FindBySkillIDAndSkillRank(ctx context.Context, a0 uint64, a1 int) (r *entity.User, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("skill_id", a0).Eq("skill_rank", a1)
	var value entity.User
	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 *UserImpl) FindBySkillIDs(ctx context.Context, a0 []uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").In("skill_id", a0)
	values := entity.Users{}
	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 *UserImpl) FindByWorldID(ctx context.Context, a0 uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("world_id", a0)
	var values entity.Users
	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 *UserImpl) FindByWorldIDAndFieldID(ctx context.Context, a0 uint64, a1 uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("world_id", a0).Eq("field_id", a1)
	var values entity.Users
	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 *UserImpl) FindByWorldIDs(ctx context.Context, a0 []uint64) (r entity.Users, e error) {
	builder := rapidash.NewQueryBuilder("users").In("world_id", a0)
	values := entity.Users{}
	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 *UserImpl) Update(ctx context.Context, value *entity.User) (e error) {
	updateMap := map[string]interface{}{
		"age":        value.Age,
		"created_at": value.CreatedAt,
		"field_id":   value.FieldID,
		"group_id":   value.GroupID,
		"name":       value.Name,
		"sex":        value.Sex,
		"skill_id":   value.SkillID,
		"skill_rank": value.SkillRank,
		"updated_at": value.UpdatedAt,
		"world_id":   value.WorldID,
	}
	builder := rapidash.NewQueryBuilder("users").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 *UserImpl) UpdateByGroupID(ctx context.Context, a0 uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("group_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 *UserImpl) UpdateByGroupIDs(ctx context.Context, a0 []uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").In("group_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 *UserImpl) UpdateByID(ctx context.Context, a0 uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").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 *UserImpl) UpdateByIDs(ctx context.Context, a0 []uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").In("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 *UserImpl) UpdateByName(ctx context.Context, a0 string, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("name", 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 *UserImpl) UpdateByNames(ctx context.Context, a0 []string, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").In("name", 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 *UserImpl) UpdateBySkillIDAndSkillRank(ctx context.Context, a0 uint64, a1 int, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("skill_id", a0).Eq("skill_rank", a1)
	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 *UserImpl) UpdateByWorldIDAndFieldID(ctx context.Context, a0 uint64, a1 uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("users").Eq("world_id", a0).Eq("field_id", a1)
	if err := d.tx.UpdateByQueryBuilderContext(ctx, builder, updateMap); err != nil {
		return xerrors.Errorf("failed to Update: %w", err)
	}
	return nil
}
