package com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson2.JSONObject;
import com.cico.nest.lcdp.boot.core.qxsd.domain.gateway.HistoryGateway;
import com.cico.nest.lcdp.boot.core.qxsd.domain.vehicle.HistoryTunnelVehicle;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.result.HkVideoResultData;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.common.result.XlwResultData;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.convertor.VehicleConvertor;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.database.TunnelEquipmentMapper;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.database.dataobject.TunnelEquipmentDO;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.http.HistoryMapper;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.http.hk.HkVideoMapper;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.http.xlw.dto.XlwHolographicTimeHistoryDTO;
import com.cico.nest.lcdp.boot.core.qxsd.infrastructure.gatewayimpl.ws.xlw.dto.XlwRealTimeVehicleDTO;
import jakarta.annotation.Resource;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author zws
 * @date 2024/8/20
 */

@Service
public class HistoryGatewayImpl implements HistoryGateway {
    @Resource
    private HistoryMapper historyMapper;
    @Resource
    private TunnelEquipmentMapper equipmentMapper;
    @Resource
    private HkVideoMapper hkVideoMapper;
    @Value("${qxsd.video.eventHisSavePath}")
    private String eventHisSaveVideoPath;

    @Override
    public String saveEventImage(String urlPath) {
        return historyMapper.saveEventImage(urlPath);
    }

    @Override
    public List<String> saveBayonetImage(String carPlate, Date eventStartTime) {
        return historyMapper.saveBayonetImage(carPlate,eventStartTime);
    }

    @Override
    public String saveVideo(String facilityId,Integer deviceMilestone,Integer direction,String beginTime,String endTime,String outputFile) {
        TunnelEquipmentDO tunnelEquipmentDO = new TunnelEquipmentDO();
        tunnelEquipmentDO.setBelongFacilityId(facilityId);
        tunnelEquipmentDO.setEquipmentStation(deviceMilestone);
        tunnelEquipmentDO.setUplinkDownlinkRoad(direction);
        List<TunnelEquipmentDO> equipmentList = equipmentMapper.getEquipmentList(tunnelEquipmentDO);
        if(CollUtil.isEmpty(equipmentList)){
            return "error未找到对应摄像头";
        }
        TunnelEquipmentDO equipmentDO = equipmentList.get(0);
        String hkVideoResultDataStr = hkVideoMapper.getPlaybackURLs(equipmentDO.getCameraIndexCode(),beginTime,endTime);
        HkVideoResultData hkVideoResultData = JSONObject.parseObject(hkVideoResultDataStr, HkVideoResultData.class);
        Object urlObject = hkVideoResultData.getData().get("url");
        if(Objects.nonNull(urlObject)){
            videoPuller(urlObject.toString(),eventHisSaveVideoPath + "/" + outputFile);
            return outputFile;
        }
        return "error获取回放视频流失败";
    }

    @Override
    public List<HistoryTunnelVehicle> getVehicleInfo(String eventId,String tunnelId,String direction,int startMilestone) {
        List<XlwHolographicTimeHistoryDTO> xlwHistoryEventList = historyMapper.getVehicleInfo(eventId);
        return VehicleConvertor.convert2HistoryTunnelVehicle(xlwHistoryEventList,tunnelId,direction,startMilestone);
    }

    public static void videoPuller(String rtspUrl, String outputFile) {
        // 创建抓取器
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtspUrl);
        try {
            grabber.start();
            // 创建录制器-设置的文件保存位置以及视频画面的宽度和高度
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile, grabber.getImageWidth(), grabber.getImageHeight());
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 设置视频编解码器
            recorder.setFormat("mp4"); // 设置视频输出格式
            // 设置音频相关参数
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
            recorder.setAudioChannels(2);
            recorder.setSampleRate(44100);
            recorder.setAudioBitrate(192000);
            recorder.start();
            Frame frame;
            while ((frame = grabber.grabFrame()) != null) {
                recorder.record(frame);
            }
            recorder.stop();
            grabber.stop();
            recorder.close();
            grabber.close();
        } catch (FrameGrabber.Exception | FrameRecorder.Exception e) {
            e.printStackTrace();
        }
    }
}
