package com.huimv.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import com.huimv.admin.common.utils.Result;
import com.huimv.admin.common.utils.ResultCode;
import com.huimv.admin.common.utils.ResultUtil;
import com.huimv.admin.entity.BasePigpen;
import com.huimv.admin.entity.CameraArea;
import com.huimv.admin.entity.CameraBase;
import com.huimv.admin.entity.CameraBrand;
import com.huimv.admin.entity.dto.CameraNameDto;
import com.huimv.admin.entity.hkwsdto.*;
import com.huimv.admin.entity.vo.*;
import com.huimv.admin.mapper.CameraAreaMapper;
import com.huimv.admin.mapper.CameraBaseMapper;
import com.huimv.admin.mapper.CameraBrandMapper;
import com.huimv.admin.service.ICameraBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-02-16
 */
@Service
public class CameraBaseServiceImpl extends ServiceImpl<CameraBaseMapper, CameraBase> implements ICameraBaseService {

    @Autowired
    private CameraAreaMapper cameraAreaMapper;
    @Autowired
    private CameraBrandMapper cameraBrandMapper;
    @Autowired
    private CameraBaseMapper cameraBaseMapper;

    @Override
    public Result listPage(CameraListVo cameraListVo) {
        Integer current = cameraListVo.getCurrent();
        String strchStr = cameraListVo.getStrchStr();
        Integer size = cameraListVo.getSize();
//        Integer areaId = cameraListVo.getAreaId();
        Integer sort = cameraListVo.getSort();
        String farmId = cameraListVo.getFarmId();
        if (farmId.equals("21")){
            farmId = "22";
        }
        Integer onLineStatus = cameraListVo.getOnLineStatus();
        String regionUuid = cameraListVo.getRegionUuid();
        QueryWrapper<CameraBase> wrapper = new QueryWrapper<>();
        if (null == current) {
            current = 1;
        }
        if (null == size) {
            size = 10;
        }
        if (farmId != null) {
            wrapper.eq("cb.farm_id", farmId);
        }
        if (StringUtils.isNotBlank(regionUuid)) {
            wrapper.eq("cb.region_uuid", regionUuid);
        }
        if (onLineStatus != null) {
            wrapper.eq("cb.on_line_status", onLineStatus);
        }
        if (StringUtils.isNotBlank(strchStr)) {
            wrapper.and(i -> i.like("cb.camera_name", strchStr));
        }
        if (sort == null) {
            wrapper.orderByDesc("cb.id");
        } else if (sort == 1) {
            wrapper.orderByDesc("cb.sort");
        } else {
            wrapper.orderByAsc("cb.sort");
        }
        wrapper.orderByDesc("cb.id");
        Page<CameraBase> page = new Page<>(current,size);
        IPage<CameraBaseVo> cameraBaseVoIPage = cameraBaseMapper.listPage(page, wrapper);
        return new Result(ResultCode.SUCCESS, cameraBaseVoIPage);
    }

    @Override
    public Result getCameraDetails(CameraListsVo cameraListsVo) {
        List<Integer> cameraIds = cameraListsVo.getCameraIds();
        CameraBrand cameraBrand = cameraBrandMapper.selectById(18);
        List list = new ArrayList();
        for (Integer cameraId : cameraIds) {
            CameraBase cameraBase = this.getById(cameraId);
            String regionUuid = cameraBase.getRegionUuid();
            CameraArea cameraArea = cameraAreaMapper.selectOne(new QueryWrapper<CameraArea>().eq("region_uuid", regionUuid));
            // http://61.153.248.106:6713/mag/hls/6bf5d2cf30bb440cad3fc126512f5188/1/live.m3u8
            String hls = "http://" + cameraArea.getPublicUrl() + cameraBrand.getStreamType() + cameraBase.getCameraUuid() + "/" + cameraBrand.getMainStream() + "/" + "live.m3u8";
            CameraVo cameraVo = new CameraVo();
            cameraVo.setHlsUrl(hls);
            cameraVo.setId(cameraBase.getId());
            cameraVo.setCameraName(cameraBase.getCameraName());
            list.add(cameraVo);
        }
        return ResultUtil.list(list);
    }


    @Override
    public void sync(Map<String, Integer> params, List<CameraDto1> list) {
        Integer farmId = params.get("farmId");

        List<CameraBase> huatongCameraBaseList = this.list(new QueryWrapper<CameraBase>().eq("farm_id", farmId));
        List<String> haikangCarmearId = list.stream().map(CameraDto1::getCameraUuid).collect(Collectors.toList());
        List<String> huatongCameraId = huatongCameraBaseList.stream().map(CameraBase::getCameraUuid).collect(Collectors.toList());
        CopyOnWriteArrayList<String> haikangDeviceIdCopy = ListUtil.toCopyOnWriteArrayList(haikangCarmearId);
        CopyOnWriteArrayList<String> huatongDeviceIdCopy = ListUtil.toCopyOnWriteArrayList(huatongCameraId);
        haikangDeviceIdCopy.removeAll(huatongCameraId);
        //TODO 想不出来，回头优化
        if (haikangDeviceIdCopy.size() > 0) {
            for (String s : haikangDeviceIdCopy) {
                for (CameraDto1 cameraDto1 : list) {
                    if (s.equals(cameraDto1.getCameraUuid())) {
                        CameraBase cameraBase = new CameraBase();
                        BeanUtil.copyProperties(cameraDto1, cameraBase);
                        CameraArea cameraArea = cameraAreaMapper.selectOne(new QueryWrapper<CameraArea>().eq("region_uuid", cameraDto1.getRegionUuid()));
                        if (ObjectUtil.isNotEmpty(cameraArea)) {
                            cameraBase.setAreaName(cameraArea.getAreaName());
                        }
//                        http://61.153.248.106:6713/mag/hls/6bf5d2cf30bb440cad3fc126512f5188/1/live.m3u8
                        cameraBase.setUrl("http://"+cameraArea.getPublicUrl()+"/mag/hls/"+cameraDto1.getCameraUuid()+"/1/live.m3u8");
                        cameraBase.setBrandName("海康威视");
                        cameraBase.setFarmId(farmId);
                        this.save(cameraBase);
                    }
                }
            }
        }
        //删除
        huatongDeviceIdCopy.removeAll(haikangCarmearId);
        if (huatongDeviceIdCopy.size() > 0) {
            this.remove(new QueryWrapper<CameraBase>().in("camera_uuid", huatongDeviceIdCopy));
        }

    }

    //更新摄像头状态
    @Override
    public void updateCameraOnlin(List<CameraDto1> list) {
        for (CameraDto1 cameraDto1 : list) {
            String cameraUuid = cameraDto1.getCameraUuid();
            CameraBase one = this.getOne(new QueryWrapper<CameraBase>().eq("camera_uuid", cameraUuid));
            one.setOnLineStatus(1 == cameraDto1.getOnLineStatus());
        }
    }

    @Override
    public Result list(HttpServletRequest httpServletRequest, Map<String, String> paramsMap) {
        String farmId = paramsMap.get("farmId");
        QueryWrapper<CameraArea> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("farm_id", farmId);
        List<CameraArea> cameraAreas = cameraAreaMapper.selectList(queryWrapper);

        List<CameraNameDto> cameraNameDtoList = new LinkedList();
        for (CameraArea cameraArea : cameraAreas) {
            CameraNameDto cameraNameDto = new CameraNameDto();
            QueryWrapper<CameraBase> baseQueryWrapper = new QueryWrapper<>();
            baseQueryWrapper.eq("farm_id", farmId).eq("area_name", cameraArea.getAreaName());
            List<CameraBase> cameraBases = cameraBaseMapper.selectList(baseQueryWrapper);

            cameraNameDto.setCameraBases(cameraBases);
            cameraNameDto.setId(cameraArea.getId());
            cameraNameDto.setAreaName(cameraArea.getAreaName());

            cameraNameDtoList.add(cameraNameDto);


        }

        return new Result(ResultCode.SUCCESS, cameraNameDtoList);
    }

    @Override
    @Transactional
    public void NewSync(Map<String, Integer> params, List<CameraDetailDto> hkvsNewCameraDtoDatumList) throws Exception {
        Integer farmId = params.get("farmId");

        this.remove(new QueryWrapper<CameraBase>().eq("farm_id", farmId));
        for (CameraDetailDto cameraDto : hkvsNewCameraDtoDatumList) {
                CameraBase cameraBase = new CameraBase();
                cameraBase.setAreaName(cameraDto.getRegionName());
                cameraBase.setCameraName(cameraDto.getName());
                cameraBase.setCameraUuid(cameraDto.getIndexCode());
                String callPostApiGetPreviewURLs = callPostApiGetPreviewURLs(cameraDto.getIndexCode());
                HkvsPreviewDto hkvsPreviewDto = JSONUtil.toBean(callPostApiGetPreviewURLs, HkvsPreviewDto.class);
                cameraBase.setUrl(hkvsPreviewDto.getData().getUrl());
                cameraBase.setCameraType(Integer.parseInt(cameraDto.getCameraType()));
                cameraBase.setCameraChannelNum(Integer.parseInt(cameraDto.getChanNum()));
                cameraBase.setUpdateTime(cameraDto.getUpdateTime());
                cameraBase.setUnitUuid(cameraDto.getParentIndexCode());
                cameraBase.setRegionUuid(cameraDto.getRegionIndexCode());
                cameraBase.setOrderNum(cameraDto.getSort());
                cameraBase.setBrandName("海康威视");
                cameraBase.setFarmId(farmId);
                this.save(cameraBase);

        }
    }


    private static final String ARTEMIS_PATH = "/artemis";

    private static final String SUBREGIONS_PATH = "/api/resource/v2/regions/subRegions";

    private static final String CAMERAS_PATH = "/api/resource/v2/camera/search";

    private static final String PREVIEW_PATH = "/api/video/v2/cameras/previewURLs";

    private static final String NEW_APPKEY = "27546900";

    private static final String NEW_SECRET = "S5qgrKdBd75M0NZRzGAh";

//    private static final String OPENAPI_IP = "61.153.248.109";
    private static final String OPENAPI_IP = "www.htzj.fun";

    private static final String ZK_REGION = "500d8b6a-2554-43f3-bda7-e686577eb741";

    private static final String PJ_REGION = "70405f14-1cb5-4413-8bef-38e4a365cbee";

    private static final String PW_REGION = "66096289-bd19-4390-a5d5-71a31e970b0b";

    /**
     * 调用POST请求类型接口，获取监控点预览取流URLv2
     * 接口实际url：https://ip:port/artemis/api/video/v2/cameras/previewURLs
     * @return
     */
    public static String callPostApiGetPreviewURLs(String cameraIndexCode) throws Exception {
        /**
         * https://ip:port/artemis/api/video/v2/cameras/previewURLs
         * 根据指定的区域编号获取该区域下的监控点列表信息，返回结果分页展示。
         * 注：返回的监控点不包括下级区域的。
         */
        ArtemisConfig config = new ArtemisConfig();
        config.setHost(OPENAPI_IP); // 代理API网关nginx服务器ip端口
        config.setAppKey(NEW_APPKEY);  // 秘钥appkey
        config.setAppSecret(NEW_SECRET);// 秘钥appSecret
        final String getCamsApi = ARTEMIS_PATH + PREVIEW_PATH;
        Map<String, Object> paramMap = new HashMap<String, Object>();// post请求Form表单参数
        paramMap.put("cameraIndexCode",cameraIndexCode);
        paramMap.put("streamType",0);
        paramMap.put("protocol","ws");
        paramMap.put("transmode",1);
        paramMap.put("expand","streamform=rtp");
        String body = JSON.toJSON(paramMap).toString();
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };
        String s = ArtemisHttpUtil.doPostStringArtemis(config, path, body, null, null, "application/json");
        System.out.println(s);

        return s;
    }

    /* *//**
     * 查询结果 转换成树形结构
     * @param bizBaseAreas 原始数据
     * @return 树
     *//*
    private List<CameraNameDto> parseBizBaseArea(List<CameraBase> bizBaseAreas){
        //构建需要展示的树形节点结构
        Map<String, CameraNameDto> nodeMap = bizBaseAreas.stream().map(basePigpen -> {
            CameraNameDto  baseVo = new CameraNameDto();
            baseVo.setId(basePigpen.getId()+"");
            baseVo.setCameraName(basePigpen.getCameraName());
            baseVo.setFarmId(basePigpen.getFarmId().toString());
            baseVo.setChildNode(new ArrayList<>());
            return baseVo;
        }).collect(Collectors.toMap(CameraNameDto::getId, b -> b,(k1, k2)->k1));
        //创建数组存父亲节点
        ArrayList<CameraNameDto> roots = new ArrayList<>();
        //构建树形
        nodeMap.values().forEach(item->{
            String parentCode = item.getParentId()+"";
            if (nodeMap.get(parentCode) == null){
                //父节点为空，说明当前节点就已经是父节点了 将该节点存起来
                roots.add(item);
            }else {
                //父节点 不为空，说明有父节点，拿到该节点的父节点的孩子节点（就是我自己),将该节点存起来
                nodeMap.get(parentCode).getChildNode().add(item);
            }
        });
        return roots;
    }*/
}
