package com.gci.boot.modules.video.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gci.boot.annotation.permission.DataPermission;
import com.gci.boot.common.log.annotation.AddSysLog;
import com.gci.boot.common.util.JsonUtil;
import com.gci.boot.common.vo.Result;
import com.gci.boot.modules.vehicles.entity.TbAccidentInfo;
import com.gci.boot.modules.video.service.IVideoService;
import com.gci.boot.modules.video.vo.CutVideoListPageVO;
import com.gci.boot.modules.video.vo.CutVideoListVO;
import com.gci.boot.modules.video.vo.ResultDeviceVO;
import com.gci.boot.modules.video.vo.VideoPlayVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/video")
public class VideoController {

    @Value("${video.baseUrl}")
    private String baseUrl;
    @Value("${video.DownloadResourceUrlSuffix}")
    private String DownloadResourceUrlSuffix;

    @Autowired
    private IVideoService videoService;
    /**
     * 测试方法
     */
    @GetMapping(value = "/videoTest")
    public Result<?> videoTest(String projectId,String id,Integer layer) {
        return Result.ok(videoService.getDeviceList(projectId,id,layer));
    }

    /**
     * 获取视频设备树形层级
     */
    @AddSysLog(value = "视频-获取视频设备树形层级")
    @DataPermission(item="tv.projectId", sqlIds = {"com.gci.boot.modules.vehicles.mapper.TbViolationRecordMapper.queryOtherVehicleProject"})
    @GetMapping(value = "/getDeviceList")
    public Result<?> getDeviceList(String projectId,String id,Integer layer) {
        return Result.ok(videoService.getDeviceList(projectId,id,layer));
    }

    /**
     * 根据车牌查视频车列表
     */
    @AddSysLog(value = "视频-根据车牌查视频车列表")
    @DataPermission(item="tb_vehicle.projectId", sqlIds = {"com.gci.boot.modules.basedata.mapper.TbVehicleMapper.selectList"})
    @GetMapping(value = "/queryDeviceList")
    public Result<?> queryDeviceList(String plateNumber) {
        return Result.ok(videoService.queryDeviceList(plateNumber));
    }

    /**
     * 获取设备实时视频
     */
    @AddSysLog(value = "视频-获取设备实时视频")
    @GetMapping(value = "/getRealPlay")
    public Result<?> getRealPlay(String simNo, Integer channelNo) {
        try{
            VideoPlayVO vo = videoService.getRealPlay(simNo,channelNo);
            return Result.ok(vo);
        }catch (Exception e){
            return Result.error(101,e.getMessage());
        }
    }

    /**
     * 获取设备历史回放
     */
    @AddSysLog(value = "视频-获取设备历史回放")
    @GetMapping(value = "/getPlayBack")
    public Result<?> getPlayBack(String simNo, Integer channelNo,String startTime, String endTime) {
        try{
            VideoPlayVO vo = videoService.getPlayBack(simNo,channelNo,startTime,endTime);
            return Result.ok(vo);
        }catch (Exception e){
            return Result.error(101,e.getMessage());
        }
    }


    /**
     * 视频云平台文件查询（同步返回）
     */
    @AddSysLog(value = "视频-视频云平台文件查询（同步返回）")
    @GetMapping(value = "/getFilesAsync")
    public Result<?> getFilesAsync(String simNo, Integer channelNo,String startTime, String endTime) {
        try{
            Object obj = videoService.getFilesAsync(simNo,channelNo,startTime,endTime);
            if(Objects.isNull(obj)){
                return Result.error(101,"车辆离线，暂无数据");
            }else{
                return Result.ok(obj);
            }
        }catch (Exception e){
            return Result.error(101,e.getMessage());
        }
    }

    /**
     * 裁剪视频
     */
    @AddSysLog(value = "视频-裁剪视频")
    @GetMapping(value = "/cutVideo")
    public Result<?> cutVideo(String sessionId,String startTime, String endTime) {
        try{
            int status = videoService.cutVideo(sessionId,startTime,endTime);
            return Result.ok(status);
        }catch (Exception e){
            return Result.error(101,e.getMessage());
        }
    }

    /**
     * 裁剪视频任务信息列表
     */
    @AddSysLog(value = "视频-裁剪视频任务信息列表")
    @GetMapping(value = "/getCutVideoList")
    public Result<?> getCutVideoList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                     String startTime, String endTime) {
        try{
            CutVideoListPageVO vo = videoService.getCutVideoList(pageNo,pageSize,startTime,endTime);
            Page<CutVideoListVO> page = new Page<CutVideoListVO>(pageNo, pageSize);
            page.setRecords(vo.getList());
            page.setTotal(vo.getCount());
            return Result.ok(page);
        }catch (Exception e){
            return Result.error(101,e.getMessage());
        }
    }

    /**
     * 媒体资源下载
     */
    @AddSysLog(value = "视频-媒体资源下载")
    @GetMapping(value = "/downloadResource")
    public Result<?> downloadResource(String fileIndex, HttpServletResponse response) {
        try{
            String token = videoService.getVedioToken();
            if(StrUtil.isBlank(token)){
                throw new RuntimeException("获取视频云平台token失败!");
            }
            if(Objects.isNull(fileIndex)){
                throw new RuntimeException("fileIndex不能为空!");
            }
            String url = baseUrl + DownloadResourceUrlSuffix;
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            Map<String, Object> param = new HashMap<>();
            param.put("fileIndex", fileIndex);
            try {
                HttpResponse execute = HttpRequest.get(url).header(headers).form(param).execute();
                if (execute.getStatus() != 200) {
                    log.warn("视频云平台媒体资源下载失败:" + execute.body());
                    throw new RuntimeException("视频云平台媒体资源下载失败!");
                } else {
                    byte[] bodyBytes = execute.bodyBytes();
                    OutputStream output = response.getOutputStream();
                    output.write(bodyBytes);
                    return Result.ok();
                }
            }catch (Exception e){
                log.warn("视频云平台媒体资源下载失败:" + e.getMessage());
                throw new RuntimeException("视频云平台媒体资源下载失败!");
            }
        }catch (Exception e){
            return Result.error(101,e.getMessage());
        }
    }
}
