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

import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.artfess.base.context.BaseContext;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.query.QueryOP;
import com.artfess.base.util.StringUtil;
import com.artfess.base.util.UniqueIdUtil;
import com.artfess.file.util.MinioUtil;
import com.artfess.uc.dao.OrgDao;
import com.artfess.uc.model.Org;
import com.artfess.yhxt.basedata.dao.BizCarEquipmentDao;
import com.artfess.yhxt.basedata.dao.BizRoadIndexCodeDao;
import com.artfess.yhxt.basedata.manager.BizCarEquipmentManager;
import com.artfess.yhxt.basedata.manager.BizRoadIndexCodeManager;
import com.artfess.yhxt.basedata.manager.RoadManager;
import com.artfess.yhxt.basedata.model.*;
import com.artfess.yhxt.basedata.dao.BizVehicleDao;
import com.artfess.yhxt.basedata.manager.BizVehicleManager;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.yhxt.basedata.vo.*;
import com.artfess.yhxt.budget.model.YearBudget;
import com.artfess.yhxt.push.HttpUtil;
import com.artfess.yhxt.specialcheck.model.BizTunnelSpecialCheck;
import com.artfess.yhxt.statistics.vo.*;
import com.artfess.yhxt.util.PermissionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import com.hikvision.artemis.sdk.config.ArtemisConfig;
import net.hasor.db.transaction.interceptor.Transactional;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 养护车辆管理 服务实现类
 *
 * @author wangping
 * @company 阿特菲斯信息技术有限公司
 * @since 2021-08-05
 */
@Service
public class BizVehicleManagerImpl extends BaseManagerImpl<BizVehicleDao, BizVehicle> implements BizVehicleManager {

    @Resource
    private BizCarEquipmentDao bizCarEquipmentDao;
    @Resource
    private BaseContext baseContext;
    @Resource
    private PermissionUtils permissionUtils;
    @Resource
    private BizRoadIndexCodeManager roadIndexCodeManager;


    @Resource
    private OrgDao orgDao;
    @Resource
    private BizVehicleManager bizVehicleManager;

    @Resource
    private RoadManager roadManager;



//    @Override
//    public List<VehicleVO> getVehicleCount() {
//        String orgId ;
//        if (StringUtils.isNotEmpty(baseContext.getCurrentOrgId())&&!"0".equals(baseContext.getCurrentOrgId())){
//            orgId = baseContext.getCurrentOrgId();
//        }else {
//            orgId = "1419863231459102720";
//        }
//        List<Org4OperatingUnitVO> operatingUnitVOS = new ArrayList<>();
//
//        List<Org4MaintenanceUnitVO> maintenanceUnitVOS = new ArrayList<>();
//
//        List<Org> rtnList = new ArrayList<>();
//
//        QueryWrapper<Org> rgQueryWrapper = new QueryWrapper<>();
//        rgQueryWrapper.eq("is_dele_","0");
//        List<Org> allList = orgDao.selectList(rgQueryWrapper);
//
//        List<Org> list = this.getOrgChild(allList, orgId, rtnList);
//        for (Org org: list){
//            Org4OperatingUnitVO fvo = new Org4OperatingUnitVO();
//            Org4MaintenanceUnitVO mvo = new Org4MaintenanceUnitVO();
//            BeanUtils.copyProperties(org,fvo);
//            BeanUtils.copyProperties(org,mvo);
//            operatingUnitVOS.add(fvo);
//            maintenanceUnitVOS.add(mvo);
//        }
//        operatingUnitVOS = getOperatingChild(operatingUnitVOS,orgId);
//
//        maintenanceUnitVOS = getMaintenanceChild(maintenanceUnitVOS,orgId);
//
//        List<VehicleVO> vos = new ArrayList<>();
//
//        VehicleVO operating = new VehicleVO();
//        operating.setName("运营单位");
//        Map<String,List<Org4OperatingUnitVO>> operatings= this.get4OperatingCount(operatingUnitVOS);
//        for (String key : operatings.keySet()){
//            operating.setChirldren(operatings.get(key));
//            operating.setCount(Integer.valueOf(key));
//        }
//        vos.add(operating);
//
//        VehicleVO maintenance = new VehicleVO();
//        maintenance.setName("养护单位");
//        Map<String,List<Org4MaintenanceUnitVO>> maintenances= this.get4MaintenanceCount(maintenanceUnitVOS);
//        for (String key : maintenances.keySet()){
//            maintenance.setChirldren(maintenances.get(key));
//            maintenance.setCount(Integer.valueOf(key));
//        }
//        vos.add(maintenance);
//
//
//        return vos;
//    }


    /**
     * naf
     * @return
     */
    @Override
    public List<VehicleCountVo> getVehicleCountVo() {
        String orgId ;
        if (StringUtils.isNotEmpty(baseContext.getCurrentOrgId())&&!"0".equals(baseContext.getCurrentOrgId())){
            orgId = baseContext.getCurrentOrgId();
        }else {
            orgId = "1419863231459102720";
        }


        List<Org> rtnList = new ArrayList<>();

        QueryWrapper<Org> rgQueryWrapper = new QueryWrapper<>();
        rgQueryWrapper.eq("is_dele_","0");
        List<Org> allList = orgDao.selectList(rgQueryWrapper);

        ArrayList<VehicleCountVo> vos = new ArrayList<>();
        List<Org> list = this.getOrgChild(allList, orgId, rtnList);
        for (Org org: list){
            VehicleCountVo vo = new VehicleCountVo();
            BeanUtils.copyProperties(org,vo);
            vos.add(vo);
        }

        List<VehicleCountVo> returnList = this.getVehicleCountChild(vos, orgId);
        this.countCompanyCount(returnList);
        return returnList;

    }


    /**
     * 最上级
     * @param vos
     * @param vos
     */
    private void countCompanyCount(List<VehicleCountVo> vos ){

        // 获取迭代器
        Iterator<VehicleCountVo> it = vos.iterator();

        while(it.hasNext()){
            VehicleCountVo vehicleCountVo = it.next();
            Integer grade = Integer.valueOf(vehicleCountVo.getGrade());
            List<String> roadList = new ArrayList<>();
            if (grade<4){
                QueryWrapper<Road> roadQueryWrapper = new QueryWrapper<>();
                roadQueryWrapper.like( "COMPANY_IDS_", vehicleCountVo.getId());
                roadList = roadManager.list(roadQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }else if (grade==4){
                QueryWrapper<Road> roadByNameQueryWrapper = new QueryWrapper<>();
                roadByNameQueryWrapper.eq("NAME_",vehicleCountVo.getName());
                roadList = roadManager.list(roadByNameQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }
            if (roadList.size()>0){
                vehicleCountVo = this.newCountVehicle(roadList,vehicleCountVo);
            }else {
                it.remove();
            }
            if (vehicleCountVo.getChirldren().size()>0&&Integer.valueOf(vehicleCountVo.getGrade())<4){
                this.countCompanyCount(vehicleCountVo.getChirldren());
            }
        }
    }

    //统计车辆
    public VehicleCountVo newCountVehicle(List<String> ids,VehicleCountVo vehicleCountVo) {

        QueryWrapper<BizVehicle> carWrapper = new QueryWrapper<>();
        carWrapper.in("ROAD_SEGMENT_ID_", ids);
        carWrapper.eq("IS_DELE_",0);
        List<BizVehicle> cars = bizVehicleManager.list(carWrapper);

        if (cars.size()>0){
            Map<Integer, Long> collect = cars.stream().filter(e -> null != e.getType()).collect(Collectors.groupingBy(BizVehicle::getType, Collectors.counting()));

            if(null == collect){
                vehicleCountVo.setBusinessNum(0L);
                vehicleCountVo.setCuringNum(0L);
            }else {
                //运营
                Long num0 = collect.get(0);
                Long num1 = collect.get(1);
                if(null != num0){
                    vehicleCountVo.setBusinessNum(num0);

                }
                if(null != num1){
                    vehicleCountVo.setCuringNum(num1);
                }

            }





            if ("4".equals(vehicleCountVo.getGrade())){
                vehicleCountVo.setRoadSegmentId(cars.get(0).getRoadSegmentId());
            }

        }
        return vehicleCountVo;
    }


    /**
     * 设置字集
     * @param vos
     * @param orgId
     * @return
     */
    private List<VehicleCountVo> getVehicleCountChild(List<VehicleCountVo> vos, String orgId) {
        List<VehicleCountVo> returnList = new ArrayList<>();
        for (VehicleCountVo entity : vos){
            if (orgId.equals(entity.getParentId())) {
                entity.setChirldren(getVehicleCountChild(vos, entity.getId()));
                returnList.add(entity);
            }
        }
        return returnList;

    }





    public Map<String,List<Org4OperatingUnitVO>> get4OperatingCount(List<Org4OperatingUnitVO> lists) {

        return this.setOperating(lists);

    }

    public Map<String,List<Org4OperatingUnitVO>> setOperating(List<Org4OperatingUnitVO> list){

        Map<String,List<Org4OperatingUnitVO>> returnMap = new HashedMap();
        // 获取迭代器
        Iterator<Org4OperatingUnitVO> it = list.iterator();
        int count = 0;
        while(it.hasNext()){
            Org4OperatingUnitVO orgVO = it.next();
            Integer grade = Integer.valueOf(orgVO.getGrade());
            List<String> roadList = new ArrayList<>();
            if (grade<4){
                QueryWrapper<Road> roadQueryWrapper = new QueryWrapper<>();
                roadQueryWrapper.like( "COMPANY_IDS_", orgVO.getId());
                roadList = roadManager.list(roadQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }else if (grade==4){
                QueryWrapper<Road> roadByNameQueryWrapper = new QueryWrapper<>();
                roadByNameQueryWrapper.eq("NAME_",orgVO.getName());
                roadList =
                        roadManager.list(roadByNameQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }
            if (roadList.size()>0){
                orgVO = this.newOperating(roadList,orgVO);
                count+=orgVO.getAllCount();
            }else {
                it.remove();
            }
            if (orgVO.getChirldren().size()>0&&Integer.valueOf(orgVO.getGrade())<4){
                this.setOperating(orgVO.getChirldren());
            }
        }
        returnMap.put(Integer.toString(count),list);
        return returnMap;
    }

    public Org4OperatingUnitVO newOperating(List<String> ids, Org4OperatingUnitVO orgVO) {

        QueryWrapper<BizVehicle> wrapper = new QueryWrapper<>();
        wrapper.in("ROAD_SEGMENT_ID_", ids);
        wrapper.eq("IS_DELE_","0");
        wrapper.eq("TYPE_",0);
        List<BizVehicle> list = this.list(wrapper);

        List<BizVehicle> patrolCar =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"10")).collect(Collectors.toList());

        orgVO.setAllCount(list.size());
        if ("4".equals(orgVO.getGrade())){
            orgVO.setRoadSegmentId(ids.get(0));
        }
        orgVO.setCarCount(patrolCar.size());
        return orgVO;
    }


    public Map<String,List<Org4MaintenanceUnitVO>> get4MaintenanceCount(List<Org4MaintenanceUnitVO> lists) {

        return this.setMaintenance(lists);

    }


    public Map<String,List<Org4MaintenanceUnitVO>> setMaintenance(List<Org4MaintenanceUnitVO> list){
        Map<String,List<Org4MaintenanceUnitVO>> returnMap = new HashedMap();
        // 获取迭代器
        Iterator<Org4MaintenanceUnitVO> it = list.iterator();

        int count = 0;
        while(it.hasNext()){
            Org4MaintenanceUnitVO orgVO = it.next();
            Integer grade = Integer.valueOf(orgVO.getGrade());
            List<String> roadList = new ArrayList<>();
            if (grade<4){
                QueryWrapper<Road> roadQueryWrapper = new QueryWrapper<>();
                roadQueryWrapper.like( "COMPANY_IDS_", orgVO.getId());
                roadList = roadManager.list(roadQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }else if (grade==4){
                QueryWrapper<Road> roadByNameQueryWrapper = new QueryWrapper<>();
                roadByNameQueryWrapper.eq("NAME_",orgVO.getName());
                roadList =
                        roadManager.list(roadByNameQueryWrapper).stream().map(Road::getId).collect(Collectors.toList());
            }
            if (roadList.size()>0){
                orgVO = this.newMaintenance(roadList,orgVO);
                count+=orgVO.getAllCount();
            }else {
                it.remove();
            }
            if (orgVO.getChirldren().size()>0&&Integer.valueOf(orgVO.getGrade())<4){
                this.setMaintenance(orgVO.getChirldren());
            }
        }
        returnMap.put(Integer.toString(count),list);
        return returnMap;
    }

    public Org4MaintenanceUnitVO newMaintenance(List<String> ids, Org4MaintenanceUnitVO orgVO) {

        QueryWrapper<BizVehicle> wrapper = new QueryWrapper<>();
        wrapper.in("ROAD_SEGMENT_ID_", ids);
        wrapper.eq("IS_DELE_","0");
        wrapper.eq("TYPE_",1);
        List<BizVehicle> list = this.list(wrapper);

        List<BizVehicle> patrolCar =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"10")).collect(Collectors.toList());

        List<BizVehicle> doubleCar =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"1")).collect(Collectors.toList());

        List<BizVehicle> tipperTruck =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"2")).collect(Collectors.toList());

        List<BizVehicle> cleanCar =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"3")).collect(Collectors.toList());

        List<BizVehicle> waterCar =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"4")).collect(Collectors.toList());

        List<BizVehicle> washingCar =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"5")).collect(Collectors.toList());

        List<BizVehicle> crane =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"6")).collect(Collectors.toList());

        List<BizVehicle> guardrail =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"7")).collect(Collectors.toList());

        List<BizVehicle> spreader =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"8")).collect(Collectors.toList());

        List<BizVehicle> aerialWork =
                list.stream().filter(vehicle -> Objects.equals(vehicle.getCarType(),"9")).collect(Collectors.toList());
        if ("4".equals(orgVO.getGrade())){
            orgVO.setRoadSegmentId(ids.get(0));
        }
        orgVO.setPatrolCar(patrolCar.size());
        orgVO.setCleanCar(cleanCar.size());
        orgVO.setAerialWork(aerialWork.size());
        orgVO.setDoubleCar(doubleCar.size());
        orgVO.setTipperTruck(tipperTruck.size());
        orgVO.setWaterCar(waterCar.size());
        orgVO.setWashingCar(washingCar.size());
        orgVO.setCrane(crane.size());
        orgVO.setGuardrail(guardrail.size());
        orgVO.setSpreader(spreader.size());
        orgVO.setAllCount(list.size());
        return orgVO;
    }


    public  List<Org> getOrgChild(List<Org> orgList, String parentId, List<Org> rtnList) {
        for (Org org : orgList) {
            // 遍历出父id等于参数的id，add进子节点集合
            if (parentId.equals(org.getParentId())) {
                // 递归遍历下一级
                this.getOrgChild(orgList, org.getId(), rtnList);
                rtnList.add(org);
            }
        }
        return rtnList;
    }

    public static List<Org4MaintenanceUnitVO> getMaintenanceChild(List<Org4MaintenanceUnitVO> allList, String pCode) {
        List<Org4MaintenanceUnitVO> returnList = new ArrayList<>();
        for (Org4MaintenanceUnitVO entity : allList){
            if (pCode.equals(entity.getParentId())) {
                entity.setChirldren(getMaintenanceChild(allList, entity.getId()));
                returnList.add(entity);
            }
        }
        return returnList;
    }


    public static List<Org4OperatingUnitVO> getOperatingChild(List<Org4OperatingUnitVO> allList, String pCode) {
        List<Org4OperatingUnitVO> returnList = new ArrayList<>();
        for (Org4OperatingUnitVO entity : allList){
            if (pCode.equals(entity.getParentId())) {
                entity.setChirldren(getOperatingChild(allList, entity.getId()));
                returnList.add(entity);
            }
        }
        return returnList;
    }





    /**
     * 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 PageList<BizVehicle> queryBizVehicle(QueryFilter<BizVehicle> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();

        IPage<BizVehicle> result = baseMapper.getBizVehicle(convert2IPage(queryFilter.getPageBean()), convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<BizVehicle>(result);
    }

    @Override
    public String minioDrawingUpload(MultipartFile file) {
        String miniourl = MinioUtil.getMinioUrl();
        if (file.isEmpty() || file.getSize() == 0) {
            throw new RuntimeException("文件为空");
        }
        String fileName = file.getOriginalFilename();
        String name = DigestUtils.md5Hex(UUID.randomUUID().toString()) + fileName.substring(fileName.lastIndexOf("."));
        String url = null;
        try {
            url = MinioUtil.uploadRelative(file, "/drawing", name, "yhxt");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return miniourl+url;

    }


    @Override
    public void minioDrawingDelete(String url) {
        String filePath = url.substring(url.lastIndexOf("/"));
        MinioUtil.removeObject("yhxt","/"+filePath, false);
    }

    @Override
    @Transactional
    public Boolean synchronizationCarData() {
        Map<String,Object> deleteMap = new HashMap<String,Object>(){
            {
                put("IS_DELE_","0");
            }
        };
        bizCarEquipmentDao.deleteByMap(deleteMap);
        String dataApi = ARTEMIS_PATH + "/api/resource/v1/regions/regionIndexCode/cameras";
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", dataApi);
            }
        };
        List<BizRoadIndexCode> roadIndexCodeList = roadIndexCodeManager.getAll();
        boolean flag = false;
        for (BizRoadIndexCode roadIndexCode : roadIndexCodeList){
            String indexCode = roadIndexCode.getIndexCode();
            if (StringUtils.isNotEmpty(indexCode)){
                Map<String,String> bodyMap = new HashMap<>();
                bodyMap.put("pageNo","1");
                bodyMap.put("pageSize","200");
                bodyMap.put("regionIndexCode",indexCode);
                bodyMap.put("treeCode","0");
                String body = JSON.toJSONString(bodyMap);
                String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json");
                JSONObject jsonObject = JSONObject.parseObject(result);
                if ("0".equals(jsonObject.get("code").toString())){
                    flag = true;
                    JSONObject dataJson = JSONObject.parseObject(jsonObject.get("data").toString());
                    List<BizCarEquipment> list = JSONArray.parseArray(dataJson.get("list").toString(), BizCarEquipment.class);
                    for (BizCarEquipment bizCarEquipment : list){
                        String str = bizCarEquipment.getName();
                        if ("50030000002160000035".equals(roadIndexCode.getIndexCode())){
                            bizCarEquipment.setName(str.substring(10,17));
                        }else {
                            bizCarEquipment.setName(str.substring(8,15));
                        }
                        bizCarEquipment.setCameraName(str.substring(str.lastIndexOf("-")+1));
                        bizCarEquipment.setRoadIndexCodeId(roadIndexCode.getId());
                        bizCarEquipment.setId(UniqueIdUtil.getSuid());
                        bizCarEquipmentDao.insert(bizCarEquipment);
                    }
                }
            }
        }
        return flag;
    }

    @Override
    public List<BizRoadIndexCodeVO> findAll() {
        QueryFilter<BizRoadIndexCode> queryFilter = (QueryFilter<BizRoadIndexCode>) QueryFilter.build().withPage(new PageBean(1, PageBean.WITHOUT_PAGE));
        if (StringUtils.isNotEmpty(baseContext.getCurrentOrgId()) ){
            permissionUtils.addPermissionNo(queryFilter);
        }
        List<BizRoadIndexCode> roadIndexCodeList = roadIndexCodeManager.query(queryFilter).getRows();
        List<BizRoadIndexCodeVO> roadIndexCodeVOS = new ArrayList<>();
        for (BizRoadIndexCode roadIndexCode : roadIndexCodeList){
            Integer allCount = 0;
            Integer onlineCount = 0;
            BizRoadIndexCodeVO roadIndexCodeVO = new BizRoadIndexCodeVO();
            BeanUtils.copyProperties(roadIndexCode,roadIndexCodeVO);
            List<BizRoadIndexCodeVO> carVOS = bizCarEquipmentDao.carNames(roadIndexCode.getId());
            for (BizRoadIndexCodeVO vo : carVOS){
                List<BizRoadIndexCodeVO> details = bizCarEquipmentDao.selectdetail(roadIndexCode.getId(),vo.getName());
                for (BizRoadIndexCodeVO onlineVO :details){
                    if ("1".equals(onlineVO.getStatus())){
                        onlineCount+=1;
                    }
                }
                vo.setList(details);
                allCount+=details.size();
            }
            roadIndexCodeVO.setList(carVOS);
            roadIndexCodeVO.setAllCount(allCount);
            roadIndexCodeVO.setOnlineCount(onlineCount);
            roadIndexCodeVOS.add(roadIndexCodeVO);

        }
        return roadIndexCodeVOS;
    }
}
