package copymission

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	goredis "github.com/redis/go-redis/v9"
)

const matrixReplaceLockTTL = 10 * time.Minute

// WithMatrixReplaceLock serializes matrix draft replacement for one copy mission.
func WithMatrixReplaceLock(
	ctx context.Context,
	redis *goredis.Client,
	tenantID, missionID, holder string,
	fn func() error,
) error {
	if fn == nil {
		return nil
	}
	tenantID = strings.TrimSpace(tenantID)
	missionID = strings.TrimSpace(missionID)
	holder = strings.TrimSpace(holder)
	if tenantID == "" || missionID == "" {
		return fn()
	}
	if redis == nil {
		return fn()
	}
	key := fmt.Sprintf("haixun:copy_matrix:%s:%s", tenantID, missionID)
	if holder == "" {
		holder = "matrix-replace"
	}
	ok, err := redis.SetNX(ctx, key, holder, matrixReplaceLockTTL).Result()
	if err != nil {
		return err
	}
	if !ok {
		return errors.New("copy matrix replacement already in progress")
	}
	defer func() {
		script := `
if redis.call("get", KEYS[1]) == ARGV[1] then
  return redis.call("del", KEYS[1])
end
return 0
`
		_ = redis.Eval(ctx, script, []string{key}, holder).Err()
	}()
	return fn()
}
