package org.dromara.app.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import lombok.RequiredArgsConstructor;
import org.dromara.app.session.AppSession;
import org.dromara.app.session.AppSessionManager;
import org.dromara.common.core.domain.R;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.time.Duration;
import java.util.List;

@RequiredArgsConstructor
@RestController
@RequestMapping("/app/session")
public class AppSessionController {

    private final AppSessionManager sessionManager;

    @GetMapping("/active")
    @SaCheckLogin
    public R<List<AppSession>> active() {
        Long userId = LoginHelper.getUserId();
        return R.ok(sessionManager.list(userId));
    }

    @PostMapping("/terminate")
    @SaCheckLogin
    public R<Boolean> terminate(@RequestParam String sessionId) {
        Long userId = LoginHelper.getUserId();
        return R.ok(sessionManager.terminate(userId, sessionId));
    }

    @PostMapping("/heartbeat")
    @SaCheckLogin
    public R<Boolean> heartbeat(@RequestParam String sessionId) {
        Long userId = LoginHelper.getUserId();
        return R.ok(sessionManager.heartbeat(userId, sessionId, Duration.ofDays(30)));
    }

    @GetMapping("/sse")
    @SaCheckLogin
    public SseEmitter sse() {
        Long userId = LoginHelper.getUserId();
        SseEmitter emitter = new SseEmitter(Duration.ofHours(1).toMillis());
        String ch = "APP:SESS_EVT:" + userId;
        org.dromara.common.redis.utils.RedisUtils.subscribe(ch, String.class, msg -> {
            try {
                emitter.send(SseEmitter.event().name("session").data(msg));
            } catch (IOException e) {
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }
}
