package com.ningdatech.carapi.car.video.manage;

import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.exception.code.ExceptionCode;
import com.ningdatech.carapi.car.equipment.manage.VehicleEquipmentManage;
import com.ningdatech.carapi.car.equipment.model.VehicleEquipmentNo;
import com.ningdatech.carapi.car.equipment.model.dto.VehicleEquipmentQueryDTO;
import com.ningdatech.carapi.car.equipment.service.IVehicleEquipmentNoService;
import com.ningdatech.carapi.car.position.contants.PositionContant;
import com.ningdatech.carapi.car.position.model.vo.DeviceVO;
import com.ningdatech.carapi.car.vehicle.contants.VehicleContant;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoService;
import com.ningdatech.carapi.car.video.model.dto.PlaybackVideoParamDTO;
import com.ningdatech.carapi.car.video.model.dto.PlaybackVideoStartParamDTO;
import com.ningdatech.carapi.car.video.model.vo.PlaybackVideoVO;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.datascope.contants.LambdaDataScopeTypeEnum;
import com.ningdatech.carapi.sys.helper.VehiclesCacheHelper;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author PoffyZhang
 * @date 2022/11/1 上午11:18
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class VideoMonitorManage {

    private final VehicleEquipmentManage vehicleEquipmentManage;

    private final RestTemplate restTemplate;

    private final VehiclesCacheHelper vehiclesCacheHelper;
    private final IVehicleBaseInfoService vehicleBaseInfoService;
    private final IVehicleEquipmentNoService vehicleEquipmentNoService;

    @Value("${vedio.host}")
    private String HOST;

    /**
     * 实时视频
     * @param carPlate
     * @return
     */
    public List<DeviceVO> getOnlineDevices(String carPlate) {
        //1.先获取 该车牌号的 所有视频设备
        //List<VehicleEquipmentQueryDTO> equipmentByCarPlate = vehicleEquipmentManage.getEquipmentByCarPlate(carPlate);
        List<VehicleEquipmentNo> equipmentByCarPlate = vehicleEquipmentNoService.list(Wrappers.lambdaQuery(VehicleEquipmentNo.class)
                .eq(VehicleEquipmentNo::getCarPlate, carPlate));
        if(CollUtil.isEmpty(equipmentByCarPlate)){
            return Collections.emptyList();
        }
        String devicesId = equipmentByCarPlate.stream()
                .map(VehicleEquipmentNo::getDeviceId)
                .collect(Collectors.joining(","));
        return equipmentByCarPlate.stream().map(o -> {
            DeviceVO deviceVO = new DeviceVO();
            deviceVO.setDeviceId(o.getDeviceId());
            deviceVO.setName(o.getDeviceName());
            deviceVO.setStatus(o.getStatus());
            return deviceVO;
        }).collect(Collectors.toList());

        //String devicesId = equipmentByCarPlate.stream()
        //        .map(VehicleEquipmentQueryDTO::getEquipmentNo)
        //        .collect(Collectors.joining(","));

        //return equipmentByCarPlate.stream().map(o -> {
        //    DeviceVO deviceVO = new DeviceVO();
        //    deviceVO.setDeviceId(o.getEquipmentNo());
        //    deviceVO.setName(o.getName());
        //    return deviceVO;
        //}).collect(Collectors.toList());
    }

    public JSONObject startPlay(String deviceId) {
        String url = String.format("%s%s/start",String.format(PositionContant.STREAM_URL,HOST),deviceId);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf("application/json"));
        HttpEntity requestEntity = new HttpEntity(String.format(""), headers);
        log.info("vedio url : {}",url);
        try{
            JSONObject response = restTemplate.postForObject(url,requestEntity,JSONObject.class);
            log.info("vedio url response : {}",response);
            if(Objects.isNull(response)){
                throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),"开始播放流失败 网络异常");
            }
            log.info("requst start play datas :{}", JSON.toJSONString(response));
            Integer statusCode = response.getInteger("status_code");
            if(0 != statusCode){
                throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),response.getString("message"));
            }
            JSONObject jsonObject  = response.getJSONObject("result");
            return jsonObject;
        }catch (Exception e){
            log.error("此次请求有异常 :" + deviceId,e);
            throw new BizException("此设备不在线 :" + deviceId);
        }
    }

    public void stopPlay(String deviceId) {
        String url = String.format( "%s%s/stop",String.format(PositionContant.STREAM_URL,HOST),deviceId);
        JSONObject response = restTemplate.postForObject(url,null,JSONObject.class);
        if(Objects.isNull(response)){
            throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),"关闭流 网络异常");
        }
        log.info("requst stop play datas :{}", JSON.toJSONString(response));
        Integer statusCode = response.getInteger("status_code");
        if (statusCode == 0){
            log.info("关闭流成功");
        }else{
            log.info("关闭流失败");
        }
    }

    /**
     * 回放视频
     * @param param
     * @return
     */
    public List<PlaybackVideoVO> playBackVideos(PlaybackVideoParamDTO param) {
        List<PlaybackVideoVO> res = Lists.newArrayList();
        //// 判断车辆是否在登录用户的区域权限内
        //NdVehicleBaseInfo car = vehiclesCacheHelper.getByCarPlate(param.getCarPlate());
        //if (Objects.isNull(car)){
        //    return Collections.emptyList();
        //}
        //LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
        //VideoMonitorManage context = (VideoMonitorManage) AopContext.currentProxy();
        //context.buildQuery(wrapper, car.getId());
        //NdVehicleBaseInfo ndVehicleBaseInfo = vehicleBaseInfoService.getOne(wrapper);
        //if (Objects.isNull(ndVehicleBaseInfo)){
        //    return Collections.emptyList();
        //}
        ////1.先获取 该车牌号的 所有设备
        //List<VehicleEquipmentQueryDTO> equipmentByCarPlate = vehicleEquipmentManage.getEquipmentByCarPlate(param.getCarPlate());
        //if(CollUtil.isEmpty(equipmentByCarPlate)){
        //    return Collections.emptyList();
        //}
        ////2.请求回放视频接口
        //for(VehicleEquipmentQueryDTO equipment : equipmentByCarPlate){
        //    if(StringUtils.isBlank(equipment.getEquipmentNo())){
        //        log.info("这个设备 {} 没有设备编号",equipment.getId());
        //        continue;
        //    }
        //    Map<String,Object> map = Maps.newConcurrentMap();
        //    map.put("deviceId",equipment.getEquipmentNo());
        //    map.put("start", param.getStart());
        //    map.put("end",param.getEnd());
        //    map.put("host",HOST);
        //    JSONObject response = restTemplate.getForObject(PositionContant.RECORD_LIST_URL,JSONObject.class,map);
        //    if(Objects.isNull(response)){
        //        throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),"回放视频数据请求失败 网络异常");
        //    }
        //    log.info("requst playback datas :{}", JSON.toJSONString(response));
        //    Integer statusCode = response.getInteger("status_code");
        //    //先不返回异常
        //    if(0 != statusCode){
        //        log.warn("运营商的历史回放视频 有异常 {}, :{}",equipment.getEquipmentNo(),response.getString("message"));
        //    }
        //    JSONObject resultJson = response.getJSONObject("result");
        //    if(Objects.isNull(resultJson)){
        //        continue;
        //    }
        //
        //    JSONArray list = resultJson.getJSONArray("list");
        //    if(Objects.isNull(list) || list.size() == 0){
        //        continue;
        //    }
        //
        //    list.stream().forEach(o -> {
        //        LinkedHashMap j = (LinkedHashMap)o;
        //        Object items = j.get("items");
        //        if(Objects.isNull(items)){
        //            return;
        //        }
        //        List<LinkedHashMap> itemList = (List<LinkedHashMap>)items;
        //        itemList.stream().forEach(item -> {
        //            PlaybackVideoVO vo = new PlaybackVideoVO(equipment.getEquipmentNo(),equipment.getName(), VehicleContant.DEFAULT_CHANNEL_NAME
        //                    ,Long.valueOf(String.valueOf(item.get("start"))),Long.valueOf(String.valueOf(item.get("end"))));
        //            res.add(vo);
        //        });
        //    });
        //}
        return res;
    }

    @LambdaDataScope(type = LambdaDataScopeTypeEnum.ALL)
    public void buildQuery(LambdaQueryWrapper<NdVehicleBaseInfo> wrapper, Long id) {
        wrapper.eq(NdVehicleBaseInfo::getId,id);
    }

    public JSONObject startPlayBack(PlaybackVideoStartParamDTO param) {
        String url = String.format("%s%s/start?start=%s&end=%s",
                String.format(PositionContant.RECORD_URL,HOST),param.getDeviceId(),param.getStart(),param.getEnd());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf("application/json"));
        HttpEntity requestEntity = new HttpEntity(String.format(""), headers);
        JSONObject response = restTemplate.postForObject(url,requestEntity,JSONObject.class);
        if(Objects.isNull(response)){
            throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),"开始播放流失败 网络异常");
        }
        log.info("requst start playback datas :{}", JSON.toJSONString(response));
        Integer statusCode = response.getInteger("status_code");
        if(0 != statusCode){
            throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),response.getString("message"));
        }
        JSONObject jsonObject = response.getJSONObject("result");
        return jsonObject;
    }

    public JSONObject stopPlayBack(String streamId) {
        String url = String.format("%s%s/stop",String.format(PositionContant.RECORD_URL,HOST),streamId);
        JSONObject response = restTemplate.postForObject(url,null,JSONObject.class);
        if(Objects.isNull(response)){
            throw new BizException(ExceptionCode.BAD_REQUEST.getCode(),"关闭流 网络异常");
        }
        log.info("requst stop playback datas :{}", JSON.toJSONString(response));
        JSONObject jsonObject  = response.getJSONObject("result");
        return jsonObject;
    }
}
