package com.artfess.yhxt.statistics.manager.impl;


import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.artfess.base.query.QueryFilter;
import com.artfess.poi.util.ExcelUtil;
import com.artfess.uc.manager.OrgManager;
import com.artfess.uc.manager.OrgUserManager;
import com.artfess.uc.manager.UserManager;
import com.artfess.uc.manager.UserRoleManager;
import com.artfess.yhxt.basedata.manager.MigrantBuildersInformationManager;
import com.artfess.yhxt.basedata.manager.RoadManager;
import com.artfess.yhxt.basedata.model.*;
import com.artfess.yhxt.businessdata.dao.CompanyDao;


import com.artfess.yhxt.open.base.vo.DataVo;
import com.artfess.yhxt.open.base.vo.RetutnVo;
import com.artfess.yhxt.statistics.dao.BaseDataStatisticsMapper;
import com.artfess.yhxt.statistics.dao.CamerasResourceDao;
import com.artfess.yhxt.statistics.dao.WorkStatisticDao;
import com.artfess.yhxt.statistics.manager.BaseDataStatisticsManager;
import com.artfess.yhxt.statistics.manager.CamerasResourceManager;
import com.artfess.yhxt.statistics.model.CamerasRequest;
import com.artfess.yhxt.statistics.model.CamerasResource;
import com.artfess.yhxt.statistics.model.PreviewURLsRequest;
import com.artfess.yhxt.statistics.model.YearBudgetSum;
import com.artfess.yhxt.statistics.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author zhx
 * @create 2021/9/1
 */
@Service
public class BaseDataStatisticsManagerImpl implements BaseDataStatisticsManager {
    @Resource
    private BaseDataStatisticsMapper baseDataStatisticsMapper;


    @Resource
    private RoadManager roadManager;
    @Resource
    private WorkStatisticDao WorkStatisticDao;

    @Resource
    private CamerasResourceManager camerasResourceManager;
    @Resource
    private CamerasResourceDao camerasResourceDao;
    //总公司id用于查询分公司的code
    private final String parentId = "1419863231459102720";

    /**
     * STEP1：设置平台参数，根据实际情况,设置host appkey appsecret 三个参数.
     */
    static {
        ArtemisConfig.host = "183.64.175.153:446";// 平台门户/nginx的IP和端口（必须使用https协议，https端口默认为443）
//        ArtemisConfig.host = "172.16.200.100:446";// 平台门户/nginx的IP和端口（必须使用https协议，https端口默认为443）
        ArtemisConfig.appKey = "29900884"; // 秘钥appkey
        ArtemisConfig.appSecret = "osPf2dpzAP9a59VQWGi6";// 秘钥appSecret
    }

    /**
     * STEP2：设置OpenAPI接口的上下文
     */
    private static final String ARTEMIS_PATH = "/artemis";

    @Override
    public Map<String, List> getBridgeStatistics(Map<String, Object> map) {
        List<Map<String, Object>> bridgeType = this.baseDataStatisticsMapper.getBridgeType(map);
        List<Map<String, Object>> bridgeShapeType = this.baseDataStatisticsMapper.getBridgeShapeType(map);
        List<Map<String, Object>> bridgeCategory = this.baseDataStatisticsMapper.getBridgeCategory(map);
        Map<String, List> listMap = new HashMap<>();
        listMap.put("bridgeType", bridgeType);
        listMap.put("bridgeShapeType", bridgeShapeType);
        listMap.put("category", bridgeCategory);
        return listMap;
    }

    @Override
    public void export(HttpServletResponse response, Map<String, Object> map) throws Exception {
        List<Map<String, Object>> bridgeShapeType = this.baseDataStatisticsMapper.getBridgeShapeType(map);
        Map<String, String> exportMap = new LinkedHashMap<>();
        exportMap.put("shapeTypeValue", "上部结构名称");
        exportMap.put("shapeTypeCount", "数量");
        exportMap.put("length", "单位总长(m)");
        HSSFWorkbook exportFile = ExcelUtil.exportExcel("上部结构信息", 22, exportMap, bridgeShapeType);
        ExcelUtil.downloadExcel(exportFile, "上部结构信息导出", response);
    }

    @Override
    public Map<String, List> getAllStructureCount(Map<String, Object> map) {
        HashMap<String, List> hashMap = new HashMap<>();
        //边坡
        List<Map<String, Object>> sideSlop = this.baseDataStatisticsMapper.getSideSlopeCount(map);
        //沿线设施
        List<Map<String, Object>> roadsideFacilities = this.baseDataStatisticsMapper.getRoadsideFacilities(map);

        //沿线设施-收费站
        List<Map<String, Object>>  roadsideFacilitiesTollStation =  this.baseDataStatisticsMapper.getRoadsideFacilitiesTollStation(map);
        //沿线设置-服务区
        List<Map<String, Object>>  roadsideFacilitiesServiceArea =  this.baseDataStatisticsMapper.getRoadsideFacilitiesServiceArea (map);
        //路段
        List<Map<String, Object>> roadSection = this.baseDataStatisticsMapper.getRoadSection(map);
        //桥梁
        List<Map<String, Object>> bridge = this.baseDataStatisticsMapper.getBridge(map);
        //隧道
        List<Map<String, Object>> tunnel = this.baseDataStatisticsMapper.getTunnel(map);
        //涵洞
        List<Map<String, Object>> culvert = this.baseDataStatisticsMapper.getCulvert(map);

        hashMap.put("sideSlop", sideSlop);
        hashMap.put("roadsideFacilities", roadsideFacilities);
        hashMap.put("roadsideFacilitiesTollStation", roadsideFacilitiesTollStation);
        hashMap.put("roadsideFacilitiesServiceArea", roadsideFacilitiesServiceArea);
        hashMap.put("roadSection", roadSection);
        hashMap.put("bridge", bridge);
        hashMap.put("tunnel", tunnel);
        hashMap.put("culvert", culvert);
        return hashMap;
    }

    @Override
    public Map<String, List> getSideSlopCompany() {
        HashMap<String, List> hashMap = new HashMap<>();
        List<Map<String, Object>> sideSlop = this.baseDataStatisticsMapper.getSideSlopCompany();
        hashMap.put("sideSlop", sideSlop);
        return hashMap;
    }

    @Override
    public Map<String, List> getRoadsideFacilitiesCompany() {
        HashMap<String, List> hashMap = new HashMap<>();
        List<Map<String, Object>> roadsideFacilities = this.baseDataStatisticsMapper.getRoadsideFacilitiesCompany();
        hashMap.put("roadsideFacilities", roadsideFacilities);
        return hashMap;
    }

    @Override
    public Map<String, List> getRoadSectionCompany() {
        HashMap<String, List> hashMap = new HashMap<>();
        List<Map<String, Object>> roadSection = this.baseDataStatisticsMapper.getRoadSectionCompany();
        hashMap.put("roadSection", roadSection);
        return hashMap;
    }

    @Override
    public Map<String, List> getBridgeCompany() {
        HashMap<String, List> hashMap = new HashMap<>();
        List<Map<String, Object>> bridge = this.baseDataStatisticsMapper.getBridgeCompany();
        hashMap.put("bridge", bridge);
        return hashMap;
    }

    @Override
    public Map<String, List> getTunnelCompany() {
        HashMap<String, List> hashMap = new HashMap<>();
        List<Map<String, Object>> tunnel = this.baseDataStatisticsMapper.getTunnelCompany();
        hashMap.put("tunnel", tunnel);
        return hashMap;
    }

    @Override
    public Map<String, List> getCulvertCompany() {
        HashMap<String, List> hashMap = new HashMap<>();
        List<Map<String, Object>> culvert = this.baseDataStatisticsMapper.getCulvertCompany();
        hashMap.put("culvert", culvert);
        return hashMap;
    }

    @Override
    public Map<String, List> getBridgeTunnelCountRanking() {
        HashMap<String, List> hashMap = new HashMap<>();
        //桥梁排行
        List<Map<String, Object>> bridgeCountRanking = this.baseDataStatisticsMapper.getBridgeCountRanking();
        //隧道排行
        List<Map<String, Object>> tunnelCountRanking = this.baseDataStatisticsMapper.getTunnelCountRanking();
        hashMap.put("bridgeCountRanking", bridgeCountRanking);
        hashMap.put("tunnelCountRanking", tunnelCountRanking);
        return hashMap;
    }

    @Override
    public Map<String, List> getTunnelStatistics(Map<String, Object> map) {
        //隧道类型
        List<Map<String, Object>> tunnelType = this.baseDataStatisticsMapper.getTunnelType(map);
        //隧道等级
        List<Map<String, Object>> tunnelGrade = this.baseDataStatisticsMapper.getTunnelGrade(map);

        HashMap<String, List> hashMap = new HashMap<>();
        hashMap.put("tunnelType", tunnelType);
        hashMap.put("tunnelGrade", tunnelGrade);

        return hashMap;
    }

  /*  @Override
    public List<MileageVo> getMileage(BaseDataParamVo baseDataParamVo) {
        ArrayList<MileageVo> mileageVos = new ArrayList<>();
        if (baseDataParamVo == null || baseDataParamVo.getCompanyId().equals("") || baseDataParamVo.getCompanyName().equals("")) {
            //获取所有的子公司
            List<Org> orgList = companyDao.getOrgsByparentId(parentId);
            for (Org org : orgList) {
                String id = org.getId();
                String name = org.getName();
                MileageVo mileageVo = this.baseDataStatisticsMapper.getMileageCount(id, name);
                if (mileageVo == null){
                     mileageVo = new MileageVo();
                    mileageVo.setCompanyName(id);
                    mileageVo.setCompanyName(name);
                    mileageVo.setMileage("0");
                }
                mileageVos.add(mileageVo);
            }
        } else {
            MileageVo mileageVo = this.baseDataStatisticsMapper.getMileageCount(baseDataParamVo.getCompanyId(), baseDataParamVo.getCompanyName());
            mileageVos.add(mileageVo);
        }


//        List<Map<String, Object>> mileage = this.baseDataStatisticsMapper.getMileage();
//        for (MileageVo mileageVo : mileageVos) {
//            for (Map<String, Object> map : mileage) {
//                String companyId = (String) map.get("companyId");
//                String companyName = (String) map.get("companyName");
//                String mileages = (String) map.get("mileage");
//                if (mileageVo.getCompanyId().equals(companyId) && mileageVo.getCompanyName().equals(companyName)) {
//                    mileageVo.setMileage(mileages);
//                }
//            }
//        }
        return mileageVos;
    }*/

    @Override
    public List<MileageVo> getRoadMileageCount(BaseDataParamVo baseDataParamVo) {
        List<MileageVo> mileageVos = this.baseDataStatisticsMapper.getRoadMileageCount(baseDataParamVo);
        return mileageVos;
    }

    @Override
    public List<MaintenanceStationVo> getMaintenanceStation(BaseDataParamVo baseDataParamVo) throws Exception {

        List<MaintenanceStationVo> maintenanceStationVos = this.baseDataStatisticsMapper.getMaintenanceStationCount(baseDataParamVo);
        return maintenanceStationVos;
    }

    @Override
    public List<CompanyUserVo> getUserCount(BaseDataParamVo baseDataParamVo) {

        List<CompanyUserVo> companyUserVos = new ArrayList<>();
        QueryWrapper<Road> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtils.isNotEmpty(baseDataParamVo.getCompanyId()), "COMPANY_ID", baseDataParamVo.getCompanyId());
        queryWrapper.eq(ObjectUtils.isNotEmpty(baseDataParamVo.getRoadSegmentId()), "ID_", baseDataParamVo.getRoadSegmentId());
        queryWrapper.eq("IS_DELE_", "0");
        List<Road> list = roadManager.list(queryWrapper);
        if (list.size() > 0) {
            for (Road road : list) {
                baseDataParamVo.setRoadSegmentId(road.getId());
                CompanyUserVo companyUserVo = this.baseDataStatisticsMapper.selectRoadSegmentUser(baseDataParamVo);
                companyUserVo.setRoadSegmentId(road.getId());
                companyUserVo.setRoadSegmentName(road.getName());
                companyUserVos.add(companyUserVo);
            }
        }
        return companyUserVos;
    }

    @Override
    public String getRoad(QueryFilter queryFilter) {
        Map<String, Object> map = queryFilter.getParams();

        List<Road> roadList = baseDataStatisticsMapper.getRoad(map);
        StringBuilder str = new StringBuilder();
        System.out.println(str);
        for (Road road : roadList) {
            str.append("[").append(road.getCode()).append(",").append(road.getName()).append(",").append(road.getStartingPoint()).append(",").append(road.getTerminalPoint()).append(",").append(road.getLength()).append("],");


        }
        if (StringUtils.isNotEmpty(str)) {
            String substring = str.substring(0, str.length() - 1);
            return substring;
        }
        return "";


    }

    @Override
    public String getRoadsideFacilities(QueryFilter queryFilter) {
        Map<String, Object> map = queryFilter.getParams();
        List<BizRoadsideFacilities> roadsides = baseDataStatisticsMapper.getRoadside(map);
        String str = "";
        for (BizRoadsideFacilities roadside : roadsides) {
            str += "[" + roadside.getCompanyName() + "," + roadside.getTypeValue() + "," + roadside.getDirectionValue() + "," + roadside.getPeg() + "," + roadside.getRoadSegmentName() + "],";
        }
        String substring = "";
        if (StringUtils.isNotEmpty(str)) {
            substring = str.substring(0, str.length() - 1);
        }
        return substring;
    }

    @Override
    public String getSideSlop(QueryFilter queryFilter) {
        Map<String, Object> map = queryFilter.getParams();
        List<SideSlopeInformation> sideSlopeInformations = baseDataStatisticsMapper.getSideSlop(map);
        String str = "";
        for (SideSlopeInformation sideSlopeInformation : sideSlopeInformations) {
            str += "[" + sideSlopeInformation.getNumber() + "," + sideSlopeInformation.getRoadSegmentName() + "," + sideSlopeInformation.getEndPeg() + "," + sideSlopeInformation.getStartPeg() + "," + sideSlopeInformation.getHeight() + "],";
        }
        String substring = "";
        if (StringUtils.isNotEmpty(str)) {
            substring = str.substring(0, str.length() - 1);
        }
        return substring;
    }

    @Override
    public String getBridgeInformation(QueryFilter queryFilter) {
        Map<String, Object> map = queryFilter.getParams();
        List<BridgeInformation> bridgeInformationList = baseDataStatisticsMapper.getBridgeInformation(map);
        String str = "";
        for (BridgeInformation bridgeInformation : bridgeInformationList) {
            str += "[" + bridgeInformation.getNumber() + "," + bridgeInformation.getName() + "," + bridgeInformation.getDirectionValue() + "," + bridgeInformation.getTypeValue() + "," + bridgeInformation.getCategoryValue() + "," + bridgeInformation.getLength() + "],";
        }
        String substring = "";
        if (StringUtils.isNotEmpty(str)) {
            substring = str.substring(0, str.length() - 1);
        }
        return substring;
    }

    @Override
    public String getTunnelInformation(QueryFilter queryFilter) {
        Map<String, Object> map = queryFilter.getParams();
        List<TunnelInformation> tunnelInformationList = baseDataStatisticsMapper.getTunnelInformation(map);
        String str = "";
        for (TunnelInformation tunnelInformation : tunnelInformationList) {
            str += "[" + tunnelInformation.getNumber() + "," + tunnelInformation.getName() + "," + tunnelInformation.getLength() + "," + tunnelInformation.getTypeValue() + "," + tunnelInformation.getGradeValue() + "],";
        }
        String substring = "";
        if (StringUtils.isNotEmpty(str)) {
            substring = str.substring(0, str.length() - 1);
        }
        return substring;
    }

    @Override
    public String getCulvertInformation(QueryFilter queryFilter) {
        Map<String, Object> map = queryFilter.getParams();
        List<BizCulvertInformation> culvertInformationList = baseDataStatisticsMapper.getCulvertInformation(map);
        String str = "";
        for (BizCulvertInformation culvertInformation : culvertInformationList) {
            str += "[" + culvertInformation.getNumber() + "," + culvertInformation.getHeight() + "," + culvertInformation.getLength() + "," + culvertInformation.getUsesValue() + "," + culvertInformation.getTypeValue() + "],";
        }
        String substring = "";
        if (StringUtils.isNotEmpty(str)) {
            substring = str.substring(0, str.length() - 1);
        }
        return substring;
    }

    @Override
    public Map getPreviewURLs(PreviewURLsRequest pr) {
        if (null == pr) {
            pr = new PreviewURLsRequest();
        }
//        if (StringUtils.isBlank(pr.getCameraIndexCode())) {
//            pr.setCameraIndexCode("110090628241674360");
//        }
        if (StringUtils.isBlank(pr.getExpand())) {
            pr.setExpand("transcode=0");
        }
        if (StringUtils.isBlank(pr.getProtocol())) {
            pr.setProtocol("ws");
        }
        if (StringUtils.isBlank(String.valueOf(pr.getTransmode()))) {
            pr.setTransmode(1);
        }
//        streamType: 0
        String str =  previewURLs(pr);
        Map map = JSONObject.parseObject(str, Map.class);
        return map;
    }

    @Override
    public List<CountRoadsideFacilities> countRoadsideFacilities(BaseDataParamVo baseDataParamVo) {
        List<CountRoadsideFacilities> countRoadsideFacilitiesList = this.baseDataStatisticsMapper.countRoadsideFacilities(baseDataParamVo);
        return countRoadsideFacilitiesList;
    }

    @Override
    public List<CountVehicleVo> countVehicle(QueryFilter queryFilter) {
        Map params = queryFilter.getParams();
        List<CountVehicleVo> countVehicleVos = new ArrayList<>();
        QueryWrapper<Road> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtils.isNotEmpty(params.get("companyId")), "COMPANY_ID", params.get("companyId"));
        queryWrapper.eq(ObjectUtils.isNotEmpty(params.get("roadSegmentId")), "ID_", params.get("roadSegmentId"));
        queryWrapper.eq("IS_DELE_", "0");
        List<Road> list = roadManager.list(queryWrapper);
        if (list.size() > 0) {
            for (Road road : list) {
                Integer countVehicle = this.baseDataStatisticsMapper.countVehicle(params, road.getId());
                CountVehicleVo countVehicleVo = new CountVehicleVo();
                countVehicleVo.setCountVehicle(String.valueOf(countVehicle));
                countVehicleVo.setRoadSegmentId(road.getId());
                countVehicleVo.setRoadSegmentName(road.getName());
                countVehicleVos.add(countVehicleVo);
            }
        }

        return countVehicleVos;
    }

    @Override
    public List<CountMileageVo> countAvgMileage(QueryFilter queryFilter) {
        Map params = queryFilter.getParams();
        Object roadSegmentId = params.get("roadSegmentId");
        List<CountMileageVo> countMileageVos = new ArrayList<>();
        QueryWrapper<Road> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtils.isNotEmpty(params.get("companyId")), "COMPANY_ID", params.get("companyId"));
        queryWrapper.eq(ObjectUtils.isNotEmpty(params.get("roadSegmentId")), "ID_", params.get("roadSegmentId"));
        queryWrapper.eq("IS_DELE_", "0");
        List<Road> list = roadManager.list(queryWrapper);
        if (list.size() > 0) {
            for (Road road : list) {
                CountMileageVo countMileageVo = new CountMileageVo();
                if (ObjectUtils.isEmpty(roadSegmentId)){
                    params.put("roadSegmentId",road.getId());
                }
                List<YearBudgetSum> yearBudgetJson = WorkStatisticDao.getYearBudgetJson(params);
                if (yearBudgetJson.size() > 0) {
                    //总金额
                    String alreadyCount = yearBudgetJson.get(0).getAlreadyCount();
                    BigDecimal totalMoney = new BigDecimal(alreadyCount);
                    //总里程
                    Map sumMileage = baseDataStatisticsMapper.countMileage(params);
                    Object mileage = sumMileage.get("mileage");
                    countMileageVo.setTotalMoney(totalMoney);
                    BigDecimal divide = (totalMoney.multiply(new BigDecimal(1000))).divide((BigDecimal) mileage, 2);
                    countMileageVo.setMileage((BigDecimal) mileage);
                    countMileageVo.setDivide(divide);
                }
                countMileageVo.setRoadSegmentId(road.getId());
                countMileageVo.setRoadSegmentName(road.getName());
                countMileageVos.add(countMileageVo);
            }

        }
        return countMileageVos;
    }

    @Override
    public List<VehicleQuantityVo> countVehicleQuantity() {
        return this.baseDataStatisticsMapper.countVehicleQuantity();
    }

    //获取监控点预览取流URL
    public String previewURLs(PreviewURLsRequest previewURLsRequest) {
        String previewURLsDataApi = ARTEMIS_PATH + "/api/video/v1/cameras/previewURLs";
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", previewURLsDataApi);
            }
        };
        String body = JSON.toJSONString(previewURLsRequest);
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
        return result;
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getCameras(CamerasRequest camerasRequest) {
        String camerasApiUrl = ARTEMIS_PATH + "/api/resource/v1/cameras";

        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", camerasApiUrl);
            }
        };

        if(null == camerasRequest.getPageNo() ){

            camerasRequest.setPageSize(1);

        }
        if(null == camerasRequest.getPageNo() ){

            camerasRequest.setPageNo(1);

        }
        if(null == camerasRequest.getTreeCode() ){

            camerasRequest.setTreeCode("0");
        }


        String body = JSON.toJSONString(camerasRequest);
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");

        RetutnVo retutnVo = JSONUtil.toBean(result, RetutnVo.class);
        DataVo data = retutnVo.getData();

        Integer total = data.getTotal();

        //循环查询插入数据库

        int pageSize =100;
        int pageNo = total / pageSize;


        int yushu = total % pageSize;

        if(yushu > 0){
            pageNo++;
        }
        camerasRequest.setPageNo(pageNo);
        camerasRequest.setPageSize(pageSize);

        //循环分业查询资源并插入到数据库
        //插入之前先删除所有数据

//        camerasResourceDao.trunate();

        for (int i = 0; i < pageNo; i++) {

            camerasRequest.setPageNo(i+1);
            String bodyi = JSON.toJSONString(camerasRequest);
            String resulti = ArtemisHttpUtil.doPostStringArtemis(path, bodyi, null, null, "application/json");

            RetutnVo retutnVoi = JSONUtil.toBean(resulti, RetutnVo.class);
            DataVo datai = retutnVoi.getData();

            List<CamerasResource> list = datai.getList();
            if(null != list && !list.isEmpty()){
                camerasResourceManager.saveOrUpdateBatch(list);
            }

        }

    }
}
