package dao

import (
	"context"
	"rapidashplugin/entity"

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

type Field interface {
	Count(context.Context) (int64, error)
	Create(context.Context, *entity.Field) error
	Delete(context.Context, *entity.Field) error
	DeleteByDifficultyAndLevel(context.Context, int, int) error
	DeleteByID(context.Context, uint64) error
	DeleteByIDs(context.Context, []uint64) error
	DeleteByLocationXAndLocationY(context.Context, int, int) error
	DeleteByName(context.Context, string) error
	DeleteByNames(context.Context, []string) error
	DeleteByObjectNum(context.Context, int) error
	DeleteByObjectNums(context.Context, []int) error
	FindAll(context.Context) (entity.Fields, error)
	FindByDifficulties(context.Context, []int) (entity.Fields, error)
	FindByDifficulty(context.Context, int) (entity.Fields, error)
	FindByDifficultyAndLevel(context.Context, int, int) (entity.Fields, error)
	FindByID(context.Context, uint64) (*entity.Field, error)
	FindByIDs(context.Context, []uint64) (entity.Fields, error)
	FindByLocationX(context.Context, int) (entity.Fields, error)
	FindByLocationXAndLocationY(context.Context, int, int) (*entity.Field, error)
	FindByLocationXes(context.Context, []int) (entity.Fields, error)
	FindByName(context.Context, string) (*entity.Field, error)
	FindByNames(context.Context, []string) (entity.Fields, error)
	FindByObjectNum(context.Context, int) (entity.Fields, error)
	FindByObjectNums(context.Context, []int) (entity.Fields, error)
	Update(context.Context, *entity.Field) error
	UpdateByDifficultyAndLevel(context.Context, int, int, map[string]interface{}) error
	UpdateByID(context.Context, uint64, map[string]interface{}) error
	UpdateByIDs(context.Context, []uint64, map[string]interface{}) error
	UpdateByLocationXAndLocationY(context.Context, int, int, map[string]interface{}) error
	UpdateByName(context.Context, string, map[string]interface{}) error
	UpdateByNames(context.Context, []string, map[string]interface{}) error
	UpdateByObjectNum(context.Context, int, map[string]interface{}) error
	UpdateByObjectNums(context.Context, []int, map[string]interface{}) error
}

type FieldImpl struct {
	tx *rapidash.Tx
}

func NewField(ctx context.Context, tx *rapidash.Tx) Field {
	return &FieldImpl{tx: tx}
}

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

// generated by eevee
func (d *FieldImpl) Delete(ctx context.Context, value *entity.Field) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) DeleteByDifficultyAndLevel(ctx context.Context, a0 int, a1 int) (e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("difficulty", a0).Eq("level", 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 *FieldImpl) DeleteByID(ctx context.Context, a0 uint64) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) DeleteByIDs(ctx context.Context, a0 []uint64) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) DeleteByLocationXAndLocationY(ctx context.Context, a0 int, a1 int) (e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("location_x", a0).Eq("location_y", 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 *FieldImpl) DeleteByName(ctx context.Context, a0 string) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) DeleteByNames(ctx context.Context, a0 []string) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) DeleteByObjectNum(ctx context.Context, a0 int) (e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("object_num", 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 *FieldImpl) DeleteByObjectNums(ctx context.Context, a0 []int) (e error) {
	builder := rapidash.NewQueryBuilder("fields").In("object_num", 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 *FieldImpl) FindAll(ctx context.Context) (r entity.Fields, e error) {
	values := entity.Fields{}
	if err := d.tx.FindAllByTable("fields", &values); err != nil {
		return values, xerrors.Errorf("failed to FindAll %w", err)
	}
	return values, nil
}

// generated by eevee
func (d *FieldImpl) FindByDifficulties(ctx context.Context, a0 []int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").In("difficulty", a0)
	values := entity.Fields{}
	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 *FieldImpl) FindByDifficulty(ctx context.Context, a0 int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("difficulty", a0)
	var values entity.Fields
	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 *FieldImpl) FindByDifficultyAndLevel(ctx context.Context, a0 int, a1 int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("difficulty", a0).Eq("level", a1)
	var values entity.Fields
	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 *FieldImpl) FindByID(ctx context.Context, a0 uint64) (r *entity.Field, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("id", a0)
	var value entity.Field
	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 *FieldImpl) FindByIDs(ctx context.Context, a0 []uint64) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").In("id", a0)
	values := entity.Fields{}
	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 *FieldImpl) FindByLocationX(ctx context.Context, a0 int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("location_x", a0)
	var values entity.Fields
	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 *FieldImpl) FindByLocationXAndLocationY(ctx context.Context, a0 int, a1 int) (r *entity.Field, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("location_x", a0).Eq("location_y", a1)
	var value entity.Field
	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 *FieldImpl) FindByLocationXes(ctx context.Context, a0 []int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").In("location_x", a0)
	values := entity.Fields{}
	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 *FieldImpl) FindByName(ctx context.Context, a0 string) (r *entity.Field, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("name", a0)
	var value entity.Field
	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 *FieldImpl) FindByNames(ctx context.Context, a0 []string) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").In("name", a0)
	values := entity.Fields{}
	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 *FieldImpl) FindByObjectNum(ctx context.Context, a0 int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("object_num", a0)
	var values entity.Fields
	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 *FieldImpl) FindByObjectNums(ctx context.Context, a0 []int) (r entity.Fields, e error) {
	builder := rapidash.NewQueryBuilder("fields").In("object_num", a0)
	values := entity.Fields{}
	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 *FieldImpl) Update(ctx context.Context, value *entity.Field) (e error) {
	updateMap := map[string]interface{}{
		"difficulty": value.Difficulty,
		"level":      value.Level,
		"location_x": value.LocationX,
		"location_y": value.LocationY,
		"name":       value.Name,
		"object_num": value.ObjectNum,
	}
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) UpdateByDifficultyAndLevel(ctx context.Context, a0 int, a1 int, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("difficulty", a0).Eq("level", 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 *FieldImpl) UpdateByID(ctx context.Context, a0 uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) UpdateByIDs(ctx context.Context, a0 []uint64, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) UpdateByLocationXAndLocationY(ctx context.Context, a0 int, a1 int, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("location_x", a0).Eq("location_y", 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 *FieldImpl) UpdateByName(ctx context.Context, a0 string, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) UpdateByNames(ctx context.Context, a0 []string, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").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 *FieldImpl) UpdateByObjectNum(ctx context.Context, a0 int, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").Eq("object_num", 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 *FieldImpl) UpdateByObjectNums(ctx context.Context, a0 []int, updateMap map[string]interface{}) (e error) {
	builder := rapidash.NewQueryBuilder("fields").In("object_num", a0)
	if err := d.tx.UpdateByQueryBuilderContext(ctx, builder, updateMap); err != nil {
		return xerrors.Errorf("failed to Update: %w", err)
	}
	return nil
}
