package cn.reghao.tnb.data.app.handler;

import cn.reghao.tnb.content.api.dto.VideoCard;
import cn.reghao.tnb.data.app.mq.MessageListenerContainerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.data.redis.connection.ReactiveSubscription;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;

/**
 * @author reghao
 * @date 2023-12-09 14:12:18
 */
@Slf4j
@Service
public class VideoHandler {
    private final ReactiveRedisOperations<String, String> eventOps;
    private final MessageListenerContainerFactory containerFactory;

    public VideoHandler(ReactiveRedisOperations<String, String> eventOps,
                        MessageListenerContainerFactory containerFactory) {
        this.eventOps = eventOps;
        this.containerFactory = containerFactory;
    }

    public Mono<ServerResponse> hotVideo(ServerRequest serverRequest) {
        return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM)
                .body(getData(), String.class);
    }

    public Mono<ServerResponse> hotVideo1(ServerRequest serverRequest) {
        return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM)
                .body(receiveMessages(), String.class);
    }

    public Flux<String> getData() {
        return Flux.interval(Duration.ofSeconds(360))
                .map(l -> new SimpleDateFormat("HH:mm:ss").format(new Date()));
    }

    public Mono<Void> putData(Flux<VideoCard> flux) {
        return null;
    }

    public Flux<String> receiveMessages() {
        /*DestinationInfo d = destinationsConfig.getQueues().get(name);
        if (d == null) {
            return Flux.just(ResponseEntity.notFound().build());
        }*/
        String routeKey = "tnb.data";
        MessageListenerContainer mlc = containerFactory.createMessageListenerContainer(routeKey);
        Flux<String> f = Flux.create(emitter -> {
            mlc.setupMessageListener(m -> {
                String payload = new String(m.getBody());
                emitter.next(payload);
            });
            emitter.onRequest(v -> {
                mlc.start();
            });
            emitter.onDispose(mlc::stop);
        });

        return Flux.interval(Duration.ofSeconds(600))
                .map(v -> "No news is good news")
                .mergeWith(f);
    }

    public Flux<String> event() {
        return Flux.interval(Duration.ofSeconds(600))
                .map(v -> "No news is good news")
                .mergeWith(eventOps.listenToChannel("topic:content")
                        .map(ReactiveSubscription.Message::getMessage)
                        .map(event -> event));
    }
}
