package com.zd.forward.serivce;

import com.zd.common.core.exception.ServiceException;
import com.zd.forward.config.AlgorithmYml;
import com.zd.forward.domain.AnalysisData;
import com.zd.forward.domain.DataPostAnalysisRespDto;
import com.zd.forward.domain.ImgPostResponse;
import com.zd.forward.properties.FireProperties;
import com.zd.forward.utils.HttpUtils;
import com.zd.forward.utils.VideoUtils;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.zd.forward.utils.HttpUtils.getHttpEntityMap;
import static com.zd.forward.utils.HttpUtils.multipartFileToFile;
import static com.zd.forward.utils.VideoUtils.frameToBufferedImage;

/**
 * 火焰图片抓拍处理
 *
 * @author Administrator
 */
@Service
@Slf4j
public class FireImageService {

    @Resource
    private FireProperties fireProperties;
    @Resource
    private AlgorithmYml algorithmYml;

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private SendSginAccessLogService sendSginAccessLogService;

    /**
     * 算法接口返回值
     */
    private static final Integer SUCCESS_CODE = 1000;

    /**
     * 生成的图片的类型
     */
    private static final String IMAGE_FORMAT = "jpg";

    public void catchImage() throws IOException {
        String streamUrl = fireProperties.getStreamUrl();
        if (streamUrl == null) {
            throw new ServiceException("未配置流媒体地址");
        }

        try (FFmpegFrameGrabber grabber = VideoUtils.createGrabber(streamUrl)) {
            grabber.start();
            String fileName = "test";
            //文件储存对象
            File file=new File(fileName+"." + IMAGE_FORMAT);
            //获取第一帧
            Frame frame = grabber.grabFrame();
            if (frame != null) {
                //视频快照
                frame = grabber.grabImage();
                BufferedImage bufferedImage = frameToBufferedImage(frame);
                if (bufferedImage != null) {
                    ImageIO.write(bufferedImage, IMAGE_FORMAT, file);
                }
                log.info("图片地址为[{}]", file.getAbsoluteFile());
                grabber.stop();
                send(file);
            }
        }
    }

    public boolean catchImage(MultipartFile file) {
        try {
            File toFile = multipartFileToFile(file);
            send(toFile);
            return true;
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }
    }

    private void send(File file) {
        if (fireProperties.getAlgoId() == null) {
            throw new ServiceException("未配置火焰算法ID");
        }
        MultiValueMap<String, Object> params = HttpUtils.getMultiValueMap(fireProperties, null);
        HttpEntity<MultiValueMap<String, Object>> files = getHttpEntityMap(file, params);
        ImgPostResponse<DataPostAnalysisRespDto> send = HttpUtils.send(restTemplate, files, algorithmYml);
        if (send == null || send.getStatus_code() != SUCCESS_CODE) {
            assert send != null;
            log.error(send.getMessage());
            return;
        }
        DataPostAnalysisRespDto data = send.getData();

        List<AnalysisData> analysisDatas = data.getAnalysisDatas();
        AnalysisData analysisData = analysisDatas.get(0);
        int code = analysisData.getCode();
        if (code==-1){
            log.error("==============请求失败：{}=================",analysisData.getMsg());
        }else {
            log.info("===============向算法服务发送数据完成====================");
            Map<String, Object> result = (Map<String, Object>) Optional.ofNullable(analysisData.getResult()).orElse(Collections.emptyMap());
            Map<String, Object> algorithmData = (Map<String, Object>) Optional.ofNullable(result.get("algorithm_data")).orElse(Collections.emptyMap());
            boolean alert = "false".equals(algorithmData.getOrDefault("is_alert", "").toString());
            if (!alert) {
                log.info("===============返回告警信息====================");
                sendSginAccessLogService.saveAlarm(fireProperties);
            }
        }
    }
}
