package cache

import (
	"context"
	"fmt"
	"log/slog"

	"github.com/costap/quarkshologridledger/tongo-core/internal/domain/entity"
	"github.com/costap/quarkshologridledger/tongo-core/internal/infrastructure/config"
	"github.com/redis/go-redis/v9"
)

// ValkeyAdapter implements port.CachePort using a Valkey (Redis-compatible) client.
type ValkeyAdapter struct {
	client *redis.Client
	logger *slog.Logger
}

// New creates a new ValkeyAdapter and tests the connection.
func New(cfg config.ValkeyConfig, logger *slog.Logger) (*ValkeyAdapter, error) {
	client := redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
		Password: cfg.Password,
		DB:       cfg.DB,
	})

	return &ValkeyAdapter{
		client: client,
		logger: logger,
	}, nil
}

// PushMatchState writes the full match telemetry to the cache.
func (v *ValkeyAdapter) PushMatchState(ctx context.Context, match *entity.Match) error {
	v.logger.Debug("Pushing match state to Valkey", "id", match.ID)
	return nil
}

// PushEvent appends an event to the match's event log.
func (v *ValkeyAdapter) PushEvent(ctx context.Context, matchID string, event entity.MatchEvent) error {
	v.logger.Debug("Pushing event to Valkey", "matchId", matchID, "eventId", event.ID)
	return nil
}

// UpdateActiveIndex updates the set of currently active match IDs.
func (v *ValkeyAdapter) UpdateActiveIndex(ctx context.Context, matchIDs []string) error {
	v.logger.Debug("Updating active match index in Valkey", "count", len(matchIDs))
	return nil
}

// UpdateQuadrantIndex updates the set of active matches for a specific quadrant.
func (v *ValkeyAdapter) UpdateQuadrantIndex(ctx context.Context, quadrantID string, matchIDs []string) error {
	v.logger.Debug("Updating quadrant index in Valkey", "quadrant", quadrantID, "count", len(matchIDs))
	return nil
}

// Ping checks that the cache connection is alive.
func (v *ValkeyAdapter) Ping(ctx context.Context) error {
	return v.client.Ping(ctx).Err()
}

// Close gracefully shuts down the cache connection.
func (v *ValkeyAdapter) Close() error {
	v.logger.Info("Closing Valkey connection")
	return v.client.Close()
}
