package cn.skcks.docking.gb28181.wvp.api.video;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.skcks.docking.gb28181.common.json.JsonResponse;
import cn.skcks.docking.gb28181.media.config.ZlmMediaConfig;
import cn.skcks.docking.gb28181.wvp.api.video.dto.RealtimeVideoReq;
import cn.skcks.docking.gb28181.wvp.api.video.dto.VideoMp4Req;
import cn.skcks.docking.gb28181.wvp.api.video.dto.VideoReq;
import cn.skcks.docking.gb28181.wvp.config.Gb28181DeviceVideoApiConfig;
import cn.skcks.docking.gb28181.wvp.config.SwaggerConfig;
import cn.skcks.docking.gb28181.wvp.config.WvpProxyConfig;
import cn.skcks.docking.gb28181.wvp.service.gb28181.Gb28181DownloadService;
import cn.skcks.docking.gb28181.wvp.service.video.VideoService;
import cn.skcks.docking.gb28181.wvp.service.wvp.WvpService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.annotations.ParameterObject;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.Date;

@Slf4j
@Tag(name = "视频api")
@Controller
@RequestMapping("/video")
@RequiredArgsConstructor
public class VideoController {
    private final ZlmMediaConfig config;
    private final VideoService videoService;
    private final WvpService wvpService;

    private final WvpProxyConfig proxyConfig;

    private final Gb28181DownloadService gb28181DownloadService;

    private final Gb28181DeviceVideoApiConfig gb28181DeviceVideoApiConfig;

    @Bean
    public GroupedOpenApi videoApi() {
        return SwaggerConfig.api("VideoApi", "/video");
    }

    @Operation(summary = "获取视频 (返回视频流)")
    @GetMapping(produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @ResponseBody
    public void video(HttpServletRequest request, HttpServletResponse response, @ParameterObject VideoReq req) {
        if(proxyConfig.getEnable()){
          wvpService.video(request,response,req.getDeviceCode(), req.getStartTime(), req.getEndTime());
        } else {
            gb28181DownloadService.video(request,response,req.getDeviceCode(), req.getStartTime(), req.getEndTime(), req.getFileHeader(), req.getUseDownload());
        }
    }

    @Operation(summary = "获取视频 (返回视频url)")
    @GetMapping(value = "/device/video.mp4")
    @ResponseBody
    public DeferredResult<JsonResponse<String>> video(@ParameterObject VideoMp4Req req) {
        long forward = gb28181DeviceVideoApiConfig.getOffset().getForward().toMillis();
        long back = gb28181DeviceVideoApiConfig.getOffset().getBack().toMillis();
        DateTime reqStartTime = DateUtil.date(req.getStartTime());
        DateTime reqEndTime = DateUtil.date(req.getEndTime());
        Date startTime = DateUtil.offsetMillisecond(reqStartTime, (int) -forward);
        Date endTime = DateUtil.offsetMillisecond(reqEndTime, (int) back);
        log.info("请求的时间范围 {} ~ {}", reqStartTime, reqEndTime);
        log.info("偏移后的时间范围 {} ~ {}", startTime, endTime);
        return gb28181DownloadService.videoUrl(req.getDeviceCode(), startTime, endTime);
    }

    @Operation(summary = "获取实时视频 (返回视频url)")
    @GetMapping(value = "/device/realtime")
    @ResponseBody
    public DeferredResult<JsonResponse<String>> realtime(@ParameterObject RealtimeVideoReq req) {
        return wvpService.realtimeVideoUrl(req.getDeviceCode());
    }

    @Operation(summary = "关闭实时视频")
    @GetMapping(value = "/device/realtime/close")
    @ResponseBody
    public JsonResponse<Void> close(@ParameterObject RealtimeVideoReq req) {
        wvpService.closeRealtimeVideo(req.getDeviceCode());
        return JsonResponse.success(null);
    }
}
