package realtime

import (
	"context"
	"strconv"
	"strings"

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

	"github.com/rycroftapparel/workpulse-api/internal/config"
)

// StartRedisSubscriber listens for cross-instance fan-out.
// Publish examples: PUBLISH workpulse:team:1 '{"type":"report.created"}', workpulse:broadcast, workpulse:user:9
func StartRedisSubscriber(ctx context.Context, cfg *config.Config, hub *Hub) func() {
	if strings.TrimSpace(cfg.RedisAddr) == "" {
		return func() {}
	}
	rdb := redis.NewClient(&redis.Options{Addr: cfg.RedisAddr})
	sub := rdb.PSubscribe(ctx, "workpulse:*")
	done := make(chan struct{})
	go func() {
		defer close(done)
		ch := sub.Channel()
		for {
			select {
			case <-ctx.Done():
				_ = sub.Close()
				return
			case msg, ok := <-ch:
				if !ok {
					return
				}
				if msg == nil {
					continue
				}
				rest := strings.TrimPrefix(msg.Channel, "workpulse:")
				switch {
				case rest == "broadcast":
					hub.BroadcastEvent("redis.message", msg.Payload)
				case strings.HasPrefix(rest, "team:"):
					hub.PublishToChannel(rest, "redis.message", msg.Payload)
				case strings.HasPrefix(rest, "user:"):
					if uid, err := strconv.ParseUint(strings.TrimPrefix(rest, "user:"), 10, 64); err == nil && strings.TrimSpace(msg.Payload) == "session.logout" {
						hub.DisconnectUser(uid)
					}
					hub.PublishToChannel(rest, "redis.message", msg.Payload)
				}
			}
		}
	}()
	return func() {
		_ = sub.Close()
		<-done
		_ = rdb.Close()
	}
}

func PublishRedis(ctx context.Context, cfg *config.Config, channel string, message string) {
	if strings.TrimSpace(cfg.RedisAddr) == "" {
		return
	}
	rdb := redis.NewClient(&redis.Options{Addr: cfg.RedisAddr})
	defer rdb.Close()
	_ = rdb.Publish(ctx, channel, message).Err()
}
