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

import com.artfess.base.context.BaseContext;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.uc.dao.OrgDao;
import com.artfess.uc.model.Org;
import com.artfess.yhxt.basedata.manager.AccessoryManager;
import com.artfess.yhxt.basedata.manager.RoadManager;
import com.artfess.yhxt.basedata.model.Accessory;
import com.artfess.yhxt.basedata.model.Road;
import com.artfess.yhxt.budget.model.YearBudget;
import com.artfess.yhxt.disease.model.Disease;
import com.artfess.yhxt.disease.dao.DiseaseDao;
import com.artfess.yhxt.disease.manager.DiseaseManager;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.yhxt.disease.vo.DiseaseReportVO;
import com.artfess.yhxt.specialcheck.model.SiteInspection;
import com.artfess.yhxt.specialcheck.vo.SiteInspecionReportVO;
import com.artfess.yhxt.statistics.vo.Org4DiseaseVO;
import com.artfess.yhxt.statistics.vo.OrgDisease4AppVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 病害管理表 服务实现类
 *
 * @author xzh
 * @company 阿特菲斯信息技术有限公司
 * @since 2021-08-09
 */
@Service
public class DiseaseManagerImpl extends BaseManagerImpl<DiseaseDao, Disease> implements DiseaseManager {


    @Resource
    private AccessoryManager accessoryManager;


    @Resource
    private OrgDao orgDao;

    @Resource
    BaseContext baseContext;

    @Resource
    private RoadManager roadManager;


    @Override
    public List<DiseaseReportVO> diseaseReport(String year,String orgId) {
        List<DiseaseReportVO> vos =  new ArrayList<>();
        QueryWrapper<Road> roadWrapper = new QueryWrapper<>();
        roadWrapper.eq("IS_DELE_","0");
        roadWrapper.like("COMPANY_IDS_",orgId);
        List<Road> roads = roadManager.list(roadWrapper);
        for (Road road : roads){
            DiseaseReportVO vo = new DiseaseReportVO();
            vo.setRoadName(road.getName());
            QueryWrapper<Disease> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("ROAD_ID_",road.getId());
            queryWrapper.apply("year(CHECK_DATE_) = {0}",year);
            List<Disease> list = this.list(queryWrapper);
            if (list.size()>0){
                vo.setDiseaseCount(list.size());
                vo.setDailyCount(list.stream()
                        .filter(p -> p.getType()==1
                                || p.getType()==2 )
                        .collect(Collectors.toList()).size());

                vo.setOftenCount(list.stream()
                        .filter(p -> p.getType()==3
                                || p.getType()==4
                                || p.getType()==5
                                || p.getType()==6)
                        .collect(Collectors.toList()).size());

                vo.setRegularCount(list.stream()
                        .filter(p -> p.getType()==7
                                || p.getType()==8
                                || p.getType()==9
                                || p.getType()==10)
                        .collect(Collectors.toList()).size());

                vo.setTemporaryCount(list.stream()
                        .filter(p -> p.getType()==11)
                        .collect(Collectors.toList()).size());

                vo.setBedCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() && p.getDiseaseCategory().equals("1"))
                        .collect(Collectors.toList()).size());

                vo.setRoadCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getDiseaseCategory().equals("2"))
                        .collect(Collectors.toList()).size());

                vo.setBridgeCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getDiseaseCategory().equals("3"))
                        .collect(Collectors.toList()).size());

                vo.setTunnelCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getDiseaseCategory().equals("4"))
                        .collect(Collectors.toList()).size());

                vo.setCulvertCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getDiseaseCategory().equals("5"))
                        .collect(Collectors.toList()).size());

                vo.setHighWallCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getDiseaseCategory().equals("6"))
                        .collect(Collectors.toList()).size());

                vo.setGreenCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getDiseaseCategory().equals("7"))
                        .collect(Collectors.toList()).size());

                vo.setUntreatedCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getHandlingSituation()!=2)
                        .collect(Collectors.toList()).size());

                vo.setFinishCount(list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getHandlingSituation()==2)
                        .collect(Collectors.toList()).size());

                if (vo.getFinishCount()>0){
                    vo.setFinishRate(new BigDecimal(vo.getFinishCount()).divide(new BigDecimal(list.size()),2,BigDecimal.ROUND_UP));
                }else {
                    vo.setFinishRate(new BigDecimal(0));
                }

                vo.setOrderCount(list.stream()
                        .filter(p -> StringUtils.isNotEmpty(p.getJobNumber()))
                        .collect(Collectors.toList()).size());

                List<Disease> finishList = list.stream()
                        .filter(p -> null != p.getDiseaseCategory() &&p.getHandlingSituation()==2)
                        .collect(Collectors.toList());
                long minutes = 0;
                for (Disease disease : finishList){
                    if(null != disease.getHandledTimeStart() && null != disease.getHandledTimeEnd()){
                        Duration dur= Duration.between(disease.getHandledTimeStart(),  disease.getHandledTimeEnd() );
                        minutes += dur.toMinutes();
                    }
                }
                vo.setHandleTime(this.turnDayHourMinuteString(new BigDecimal(minutes).divide(new BigDecimal(list.size()),0,BigDecimal.ROUND_UP).longValue()));
            }else {
                vo.setFinishRate(new BigDecimal(0));
                vo.setHandleTime("0分钟");
            }

            vos.add(vo);
        }
        return vos;
    }

    public  String turnDayHourMinuteString(long minute) {
        //如果传入的分钟是0，默认24小时
        if (0 == minute) {
            return 0 + "分钟";
        }
        //如果分钟小于60，默认返回分钟
        if (0 < minute && minute < 60) {
            return minute + "分钟";
        }
        //如果分钟小于24小时（1440分钟），返回小时和分钟
        if (60 <= minute && minute < 1440) {

            if (minute % 60 == 0) {
                long h = minute / 60;
                return h + "小时";
            } else {
                long h = minute / 60;
                long m = minute % 60;
                return h + "小时" + m + "分钟";
            }

        }
        //如果分钟大于1天
        if (minute >= 1440) {

            long d = minute / 60 / 24;
            long h = minute / 60 % 24;
            long m = minute % 60;
            String s1 = null;
            if (d > 0) {
                s1 = d + "天";
            }
            //h如果计算大于等于1再展示，否则只展示天和分钟
            if (h >= 1) {
                s1 += h + "小时";
            }
            if (m > 0) {
                s1 += m + "分钟";
            }

            return s1;
        }
        return null;
    }


    @Override
    public OrgDisease4AppVO getDisease4AppCount(String level,String dimension,String date) {

        if ("0".equals(level)){
            dimension = "1419863231459102720";
        }

        Org org = orgDao.get(dimension);

        OrgDisease4AppVO fvo = new OrgDisease4AppVO();
        BeanUtils.copyProperties(org,fvo);


        return this.setCount4App(fvo,date);
    }


    public OrgDisease4AppVO setCount4App(OrgDisease4AppVO orgVO,String year){

        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.diseaseCount4App(roadList,orgVO,year);
        }else {
            orgVO.setCount(0);
        }

        return orgVO;
    }

    //日报接口
    public OrgDisease4AppVO diseaseCount4App(List<String> ids,OrgDisease4AppVO orgVO,String date) {
        QueryWrapper<Disease> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.in("ROAD_ID_", ids);
        orderQueryWrapper.apply("date_format(CREATE_TIME_,'%Y-%m-%d') = {0}", date);
        List<Disease> list = this.list(orderQueryWrapper);
        if (list.size()>0){
            List<Disease> r0List = list.stream().filter(student -> Objects.equals(student.getHandlingSituation(),0)).collect(Collectors.toList());
            orgVO.setRunCount(r0List.size());
            List<Disease> r1List = list.stream().filter(student -> Objects.equals(student.getHandlingSituation(),1)).collect(Collectors.toList());
            orgVO.setFinishCount(r1List.size());
            orgVO.setCount(list.size());

        }else {
            orgVO.setCount(0);
        }
        return orgVO;
    }

    @Override
    public List<Org4DiseaseVO> getDiseaseCount(String year) {
        String orgId ;
        if (StringUtils.isNotEmpty(baseContext.getCurrentOrgId())&&!"0".equals(baseContext.getCurrentOrgId())){
            orgId = baseContext.getCurrentOrgId();
        }else {
            orgId = "1419863231459102720";
        }
        List<Org4DiseaseVO> lists = new ArrayList<>();

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

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

        List<Org> list = getOrgChild(allList, orgId, rtnList);
        for (Org org: list){
            Org4DiseaseVO fvo = new Org4DiseaseVO();
            BeanUtils.copyProperties(org,fvo);
            lists.add(fvo);
        }
        lists = getChild(lists,orgId);


        return this.setCount(lists,year);
    }




    public List<Org4DiseaseVO> setCount(List<Org4DiseaseVO> list,String year){

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

        while(it.hasNext()){
            Org4DiseaseVO 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.newCountDisease(roadList,orgVO,year);
            }else {
                it.remove();
            }
            if (orgVO.getChirldren().size()>0&&Integer.valueOf(orgVO.getGrade())<4){
                this.setCount(orgVO.getChirldren(),year);
            }
        }
        return list;
    }

    //统计表格
    public Org4DiseaseVO newCountDisease(List<String> ids,Org4DiseaseVO orgVO,String year) {
        QueryWrapper<Disease> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.in("ROAD_ID_", ids);
        orderQueryWrapper.apply("year(CHECK_DATE_) = {0}",year);
        List<Disease> list = this.list(orderQueryWrapper);
        if (list.size()>0){
            //位处理
            List<Disease> r0List = list.stream().filter(e -> e.getHandlingSituation().equals(0) &&  e.getTemporary().equals(0)).collect(Collectors.toList());
            orgVO.setRunCount(r0List.size());
            //以处理
            List<Disease> r1List = list.stream().filter(student -> Objects.equals(student.getHandlingSituation(),2)).collect(Collectors.toList());
            orgVO.setFinishCount(r1List.size());
            //暂存
            List<Disease> r2List = list.stream().filter(student -> Objects.equals(student.getTemporary(),1)).collect(Collectors.toList());
            orgVO.setTemporaryCount(r2List.size());

            if ("4".equals(orgVO.getGrade())){
                orgVO.setRoadSegmentId(list.get(0).getRoadId());
            }
        }else {
            orgVO.setTemporaryCount(0);
            orgVO.setFinishCount(0);
            orgVO.setRunCount(0);
        }
        return orgVO;
    }

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

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



    @Override
    public PageList<Disease> queryDisease(QueryFilter<Disease> queryFilter) {
        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        IPage<Disease> result = baseMapper.getDisease(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<>(result);
    }

    @Override
    public Accessory minioDiseaseUpload(MultipartFile file, String sourceId) {
        /*String minioUrl = MinioUtil.getMinioUrl();
        Accessory accessory = new Accessory();
        accessory.setSourceId(sourceId);
        if (file.isEmpty() || file.getSize() == 0) {
            throw new RuntimeException("文件为空");
        }

        try {

            String fileName = file.getOriginalFilename();
            System.out.println(fileName);
            accessory.setName(fileName);
            String name = DigestUtils.md5Hex(UUID.randomUUID().toString())+fileName.substring(fileName.lastIndexOf("."));

            String url = MinioUtil.uploadRelative(file, "/drawing", name, "yhxt");
            //验证图片类型
            String ext = fileName.substring(fileName.lastIndexOf(".")+1);
            System.out.println(ext);
            accessory.setType(ext);
            accessory.setSuffix(ext);
            accessory.setUrl(url);
            accessory.setIsDele("0");
            this.accessoryDao.insert(accessory);
            accessory.setMinioUrl(minioUrl+url);
            return accessory;
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        return this.accessoryManager.minIoUpload(file, "drawing", "", "yhxt", sourceId);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void minioDiseaseDel(List<String> asList) {
        asList.forEach(s -> {

            this.accessoryManager.minIoRemoveFile(s, "drawing", "yhxt");
        });
    }

    @Override
    public void minIoDiseaseDownFile(String ids, HttpServletResponse response) throws Exception {
        this.accessoryManager.minIoDownFile(ids, "drawing", "download/drawing", "yhxt", response);
    }

    @Override
    public PageList<Disease> getJsonBridgeDiseaseCheck(QueryFilter<Disease> queryFilter) {
        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        IPage<Disease> result = null;
        if ((Integer) queryFilter.getParams().get("flag") == 0) {
            result = baseMapper.getJsonDiseaseOftenCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        } else if ((Integer) queryFilter.getParams().get("flag") == 1) {
            result = baseMapper.getJsonDiseaseRegularCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        }
        return new PageList<>(result);

    }

    @Override
    public PageList<Disease> getJsonCulvertDiseaseCheck(QueryFilter<Disease> queryFilter) {

        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        IPage<Disease> result = null;
        if ((Integer) queryFilter.getParams().get("flag") == 0) {
            result = baseMapper.getCulvertDiseaseOftenCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        } else if ((Integer) queryFilter.getParams().get("flag") == 1) {
            result = baseMapper.getCulvertDiseaseRegularCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        }
        return new PageList<>(result);
    }

    @Override
    public PageList<Disease> getJsonTunnelDiseaseCheck(QueryFilter<Disease> queryFilter) {

        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        IPage<Disease> result = null;
        if ((Integer) queryFilter.getParams().get("flag") == 0) {
            result = baseMapper.getTunnelDiseaseOftenCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        } else if ((Integer) queryFilter.getParams().get("flag") == 1) {
            result = baseMapper.getTunnelDiseaseRegularCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        }
        return new PageList<>(result);
    }

    @Override
    public PageList<Disease> getJsonSideDiseaseCheck(QueryFilter<Disease> queryFilter) {

        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        IPage<Disease> result = null;
        Integer flag = (Integer) queryFilter.getParams().get("flag");
        if (flag == 0) {
            result = baseMapper.getSideDiseaseOftenCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        } else if (flag == 1) {
            result = baseMapper.getSideDiseaseRegularCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        }
        return new PageList<>(result);
    }

    @Override
    public LocalDateTime calculateDeadline(LocalDateTime checkDate) {
        //查询配置病害超时天数
        String days = baseMapper.diseaseTimeDays();

        return checkDate.plusDays(Long.parseLong(days));

    }

    @Override
    public void saveDiseaseVo(Disease disease) {
        //保存病害信息

        this.create(disease);
        //资源ID
        String id = disease.getId();
        //获取附件信息
        List<Accessory> accessoryList = disease.getAccessories();
        if (accessoryList!=null &&accessoryList.size() > 0) {
            accessoryList.forEach(s -> s.setSourceId(id));
            this.accessoryManager.saveBatch(accessoryList);
        }
    }

    @Override
    public void updateDiseaseVo(Disease disease) {
        //保存病害信息
        this.update(disease);
        //资源ID
        String id = disease.getId();

        //获取附件信息
        List<Accessory> accessoryList = disease.getAccessories();
        if (accessoryList.size()>0) {
            this.accessoryManager.delAccessoryBySourceId(id);
            accessoryList.forEach(s -> s.setSourceId(id));
            this.accessoryManager.saveOrUpdateBatch(accessoryList);
        }
    }

    @Override
    public Disease getByIdDisease(String id) {
        Disease disease = this.getById(id);
        List<Accessory> accessories = this.accessoryManager.getAccessoryBySourceId(id);
        disease.setAccessories(accessories);
        return disease;
    }
}
