package memdb

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/pov-service/internal/common/errors"
	"github.com/tidbcloud/pov-service/internal/model"
	"github.com/tidbcloud/pov-service/internal/repo"
)

type workloadTest struct {
	db map[string]*model.WorkloadTest
}

func NewWorkloadTest() workloadTest {
	return workloadTest{
		db: make(map[string]*model.WorkloadTest),
	}
}

func (w workloadTest) Create(
	ctx context.Context,
	workload model.WorkloadTest) (model.WorkloadTest, error) {
	if _, ok := w.db[workload.ID]; ok {
		return model.WorkloadTest{}, fmt.Errorf("workload %s already exists", workload.ID)
	}
	now := time.Now().UTC()
	workload.CreatedAt = now
	workload.UpdatedAt = &now

	w.db[workload.ID] = &workload
	return workload, nil

}

func (w workloadTest) Update(
	ctx context.Context,
	workload model.WorkloadTest) (model.WorkloadTest, error) {
	if _, ok := w.db[workload.ID]; !ok {
		return model.WorkloadTest{}, fmt.Errorf("workload %s not found", workload.ID)
	}

	now := time.Now().UTC()
	workload.UpdatedAt = &now

	w.db[workload.ID] = &workload
	return workload, nil
}

func (w workloadTest) Get(
	ctx context.Context,
	ID string) (model.WorkloadTest, error) {
	if v, ok := w.db[ID]; !ok {
		return model.WorkloadTest{}, errors.NewNotFound(fmt.Sprintf("workload %s not found", ID))
	} else {
		return *v, nil
	}
}

func (w workloadTest) ListActive(ctx context.Context) ([]model.WorkloadTest, error) {
	ret := make([]model.WorkloadTest, 0)
	for _, v := range w.db {
		if v.IsActive() {
			ret = append(ret, *v)
		}
	}
	return ret, nil
}

// Transaction-based methods - simplified for in-memory implementation
func (w workloadTest) BeginTx(ctx context.Context) (repo.Tx, error) {
	return &memTx{}, nil
}

func (w workloadTest) GetAndLockForUpdateInTx(ctx context.Context, tx repo.Tx, ID string) (model.WorkloadTest, error) {
	// For in-memory implementation, just delegate to regular Get
	return w.Get(ctx, ID)
}

func (w workloadTest) UpdateInTx(ctx context.Context, tx repo.Tx, workload model.WorkloadTest) error {
	_, err := w.Update(ctx, workload)
	return err
}

// memTx implements the repo.Tx interface for in-memory database
type memTx struct{}

func (t *memTx) Commit() error {
	return nil
}

func (t *memTx) Rollback() error {
	return nil
}
