package com.artfess.yhxt.check.regular.manager.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.*;
import com.artfess.yhxt.basedata.manager.*;
import com.artfess.yhxt.basedata.model.*;
import com.artfess.yhxt.check.detail.dao.BridgeOftenCheckDetailDao;
import com.artfess.yhxt.check.detail.manager.BridgeOftenCheckDetailManager;
import com.artfess.yhxt.check.detail.model.BridgeOftenCheckDetail;
import com.artfess.yhxt.check.regular.dao.BridgeOftenCheckDao;
import com.artfess.yhxt.check.regular.manager.BridgeOftenCheckManager;
import com.artfess.yhxt.check.regular.manager.CulvertOftenCheckManager;
import com.artfess.yhxt.check.regular.manager.SideSlopeOftenCheckManager;
import com.artfess.yhxt.check.regular.manager.TunnelOftenCheckManager;
import com.artfess.yhxt.check.regular.model.BridgeOftenCheck;
import com.artfess.yhxt.check.regular.model.CulvertOftenCheck;
import com.artfess.yhxt.check.regular.model.SideSlopeOftenCheck;
import com.artfess.yhxt.check.regular.model.TunnelOftenCheck;
import com.artfess.yhxt.check.regular.vo.BridgeOftenCheckVo;
import com.artfess.yhxt.check.regular.vo.CheckReportVO;
import com.artfess.yhxt.contract.vo.OrderReportVO;
import com.artfess.yhxt.statistics.dao.SiteStatisticDao;
import com.artfess.yhxt.statistics.model.SiteStatistic;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.io.InputStream;
import java.util.stream.Collectors;

/**
 * 桥梁经常检查表 服务实现类
 *
 * @author xzh
 * @company 阿特菲斯信息技术有限公司
 * @since 2021-08-03
 */
@Service
public class BridgeOftenCheckManagerImpl extends BaseManagerImpl<BridgeOftenCheckDao, BridgeOftenCheck> implements BridgeOftenCheckManager {

    @Resource
    private BridgeOftenCheckDetailManager bridgeOftenCheckDetailManager;

    @Resource
    private BridgeOftenCheckDetailDao bridgeOftenCheckDetailDao;

    @Resource
    private SiteStatisticDao siteStatisticDao;
    @Resource
    private BridgeInformationManager bridgeInformationManager;

    @Resource
    private RoadManager roadManager;
    @Resource
    private AccessoryManager accessoryManager;


    @Resource
    private TunnelInformationManager tunnelInformationManager;

    @Resource
    private TunnelOftenCheckManager tunnelOftenCheckManager;

    @Resource
    private BizCulvertInformationManager bizCulvertInformationManager;

    @Resource
    private CulvertOftenCheckManager culvertOftenCheckManager;

    @Resource
    private SideSlopeInformationManager sideSlopeInformationManager;

    @Resource
    private SideSlopeOftenCheckManager sideSlopeOftenCheckManager;

    @Override
    public List<CheckReportVO> checkReport(String year, String orgId) {
        List<CheckReportVO> vos =  new ArrayList<>();
        QueryWrapper<Road> roadWrapper = new QueryWrapper<>();
        roadWrapper.eq("IS_DELE_","0");
        roadWrapper.like("COMPANY_IDS_",orgId);
        List<Road> roads = roadManager.list(roadWrapper);
        LocalDateTime now = LocalDateTime.now();
        int month = now.getMonthValue();
        Calendar calendar = Calendar.getInstance();
        for (Road road : roads){
            CheckReportVO vo = new CheckReportVO();
            vo.setRoadName(road.getName());
            //桥梁
            QueryWrapper<BridgeInformation> bridgeWrapper = new QueryWrapper<>();
            bridgeWrapper.eq("IS_DELE_","0");
            bridgeWrapper.eq("ROAD_SEGMENT_ID_",road.getId());
            List<BridgeInformation> bridges = bridgeInformationManager.list(bridgeWrapper);
            //隧道
            QueryWrapper<TunnelInformation> tunnelWrapper = new QueryWrapper<>();
            tunnelWrapper.eq("IS_DELE_","0");
            tunnelWrapper.eq("ROAD_SEGMENT_ID_",road.getId());
            List<TunnelInformation> tunnels = tunnelInformationManager.list(tunnelWrapper);
            //涵洞
            QueryWrapper<BizCulvertInformation> culvertWrapper = new QueryWrapper<>();
            culvertWrapper.eq("IS_DELE_","0");
            culvertWrapper.eq("ROAD_SEGMENT_ID_",road.getId());
            List<BizCulvertInformation> culverts = bizCulvertInformationManager.list(culvertWrapper);
            //边坡
            QueryWrapper<SideSlopeInformation> sideWrapper = new QueryWrapper<>();
            sideWrapper.eq("IS_DELE_","0");
            sideWrapper.eq("ROAD_SEGMENT_ID_",road.getId());
            List<SideSlopeInformation> sides = sideSlopeInformationManager.list(sideWrapper);
            vo.setBridgeCount(bridges.size());
            vo.setTunnelCount(tunnels.size());
            vo.setCulvertCount(culverts.size());
            vo.setSideCount(sides.size());
            vo.setAllCount(bridges.size()+tunnels.size()+culverts.size()+sides.size());
            if (bridges.size()>0){
                //桥梁年检查次数
                QueryWrapper<BridgeOftenCheck> bridgeCheckWrapper = new QueryWrapper<>();
                bridgeCheckWrapper.eq("IS_DELE_","0");
                bridgeCheckWrapper.in("BRIGE_ID_",bridges.stream().map(BridgeInformation::getId).collect(Collectors.toList()));
                bridgeCheckWrapper.apply("date_format(CHECK_DATE_,'%Y') = {0}", year);
                List<BridgeOftenCheck> bridgechecks = this.list(bridgeCheckWrapper);
                vo.setBridgeCheckCount(bridgechecks.size());


                List<BridgeOftenCheck> monthBrideg = new ArrayList<>();
                for (BridgeOftenCheck check : bridgechecks){
                    calendar.setTime(check.getCheckDate());
                    if (calendar.get(Calendar.MONTH)+1==month){
                        monthBrideg.add(check);
                    }
                }

                vo.setBridgeMonthCheckCount(monthBrideg.size());
            }


            if (tunnels.size()>0){
                //隧道年检查次数
                QueryWrapper<TunnelOftenCheck> tunnelCheckWrapper = new QueryWrapper<>();
                tunnelCheckWrapper.eq("IS_DELE_","0");
                tunnelCheckWrapper.in("TUNNEL_ID_",tunnels.stream().map(TunnelInformation::getId).collect(Collectors.toList()));
                tunnelCheckWrapper.apply("date_format(CHECK_DATE_,'%Y') = {0}", year);
                List<TunnelOftenCheck> tunnelchecks = tunnelOftenCheckManager.list(tunnelCheckWrapper);
                vo.setTunnelCheckCount(tunnelchecks.size());

                List<TunnelOftenCheck> monthTunnel = new ArrayList<>();
                for (TunnelOftenCheck check : tunnelchecks){
                    calendar.setTime(check.getCheckDate());
                    if (calendar.get(Calendar.MONTH)+1==month){
                        monthTunnel.add(check);
                    }
                }

                vo.setTunnelMonthCheckCount(monthTunnel.size());
            }


            if (culverts.size()>0){
                //涵洞年检查次数
                QueryWrapper<CulvertOftenCheck> culvertCheckWrapper = new QueryWrapper<>();
                culvertCheckWrapper.eq("IS_DELE_","0");
                culvertCheckWrapper.in("CULVERT_ID_",culverts.stream().map(BizCulvertInformation::getId).collect(Collectors.toList()));
                culvertCheckWrapper.apply("date_format(CHECK_DATE_,'%Y') = {0}", year);
                List<CulvertOftenCheck> culvertchecks = culvertOftenCheckManager.list(culvertCheckWrapper);
                vo.setCulvertCheckCount(culvertchecks.size());

                List<CulvertOftenCheck> monthCulvert = new ArrayList<>();
                for (CulvertOftenCheck check : culvertchecks){
                    calendar.setTime(check.getCheckDate());
                    if (calendar.get(Calendar.MONTH)+1==month){
                        monthCulvert.add(check);
                    }
                }
                vo.setCulvertMonthCheckCount(monthCulvert.size());
            }





            if (sides.size()>0){
                //边坡年检查次数
                QueryWrapper<SideSlopeOftenCheck> sideCheckWrapper = new QueryWrapper<>();
                sideCheckWrapper.eq("IS_DELE_","0");
                sideCheckWrapper.in("SIDE_SLOPE_ID_",sides.stream().map(SideSlopeInformation::getId).collect(Collectors.toList()));
                sideCheckWrapper.apply("date_format(CHECK_DATE_,'%Y') = {0}", year);
                List<SideSlopeOftenCheck> sidechecks = sideSlopeOftenCheckManager.list(sideCheckWrapper);
                vo.setSideCheckCount(sidechecks.size());

                List<SideSlopeOftenCheck> monthSide = new ArrayList<>();
                for (SideSlopeOftenCheck check : sidechecks){
                    calendar.setTime(check.getCheckDate());
                    if (calendar.get(Calendar.MONTH)+1==month){
                        monthSide.add(check);
                    }
                }
                vo.setSideMonthCheckCount(monthSide.size());
            }


            if (vo.getBridgeCheckCount()>0){
                vo.setBridgeMonthRate(new BigDecimal(vo.getBridgeCheckCount()).divide(new BigDecimal(month),2,BigDecimal.ROUND_UP));
            }else {
                vo.setBridgeMonthRate(BigDecimal.ZERO);
            }

            if (vo.getTunnelCheckCount()>0){
                vo.setTunnelMonthRate(new BigDecimal(vo.getTunnelCheckCount()).divide(new BigDecimal(month),2,BigDecimal.ROUND_UP));
            }else {
                vo.setTunnelMonthRate(BigDecimal.ZERO);
            }

            if (vo.getCulvertCheckCount()>0){
                vo.setCulvertMonthRate(new BigDecimal(vo.getCulvertCheckCount()).divide(new BigDecimal(month),2,BigDecimal.ROUND_UP));
            }else {
                vo.setCulvertMonthRate(BigDecimal.ZERO);
            }

            if (vo.getSideCheckCount()>0){
                vo.setSideMonthRate(new BigDecimal(vo.getSideCheckCount()).divide(new BigDecimal(month),2,BigDecimal.ROUND_UP));
            }else {
                vo.setSideMonthRate(BigDecimal.ZERO);
            }

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

    @Override
    public PageList<BridgeOftenCheck> queryBridgeOftenCheck(QueryFilter<BridgeOftenCheck> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        HashMap<String, Object> map = new HashMap<>();
        Map<String, Object> params = queryFilter.getParams();
        if (params != null) {
            map.putAll(params);
        }
        List<FieldSort> sorter = queryFilter.getSorter();
        if(null == sorter || sorter.isEmpty()){
            sorter.add(new FieldSort("CHECK_DATE_", Direction.DESC));
            queryFilter.setSorter(sorter);
        }
        IPage<BridgeOftenCheck> result = baseMapper.queryBridgeOftenCheck(convert2IPage(queryFilter.getPageBean()), map, convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<>(result);
    }

    @Override
    public void saveBridgeOftenCheck(BridgeOftenCheckVo vo) {
        BridgeOftenCheck bridgeOftenCheck = vo.getBridgeOftenCheck();
        bridgeOftenCheck.setIsDele("0");
        this.saveOrUpdate(bridgeOftenCheck);
        vo.getBridgeDetailList().forEach(s -> {
            s.setId(null);
            s.setBridgeOftenCheckId(bridgeOftenCheck.getId());
            this.bridgeOftenCheckDetailManager.save(s);
        });
        //保存附件信息
        List<Accessory> accessoryList = vo.getAccessories();
        //资源ID
        String id = bridgeOftenCheck.getId();
        if (null !=accessoryList && accessoryList.size() > 0) {
            //获取附件信息
            accessoryList.forEach(s -> s.setSourceId(id));
            this.accessoryManager.saveBatch(accessoryList);
        }

    }

    @Override
    public void updateBridgeOftenCheck(BridgeOftenCheckVo vo) {
        BridgeOftenCheck bridgeOftenCheck = vo.getBridgeOftenCheck();
        this.update(bridgeOftenCheck);
        vo.getBridgeDetailList().forEach(s -> {
            s.setBridgeOftenCheckId(bridgeOftenCheck.getId());
            this.bridgeOftenCheckDetailManager.saveOrUpdate(s);
        });
        //保存附件信息
        List<Accessory> accessoryList = vo.getAccessories();
        //资源ID
        String id = bridgeOftenCheck.getId();
        if (null !=accessoryList && accessoryList.size() > 0) {
            //删除原来的附件信息
            this.accessoryManager.delAccessoryBySourceId(id);
            //获取附件信息
            accessoryList.forEach(s -> s.setSourceId(id));
            this.accessoryManager.saveOrUpdateBatch(accessoryList);
        }
    }

    @Override
    public BridgeOftenCheckVo getBridgeOftenCheckById(String id) {
        BridgeOftenCheckVo checkVo = new BridgeOftenCheckVo();
        BridgeOftenCheck bridgeOftenCheck = this.getById(id);
        checkVo.setBridgeOftenCheck(bridgeOftenCheck);
        QueryWrapper<BridgeOftenCheckDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(bridgeOftenCheck.getId()), "BRIDGE_OFTEN_CHECK_ID_", bridgeOftenCheck.getId());
        List<BridgeOftenCheckDetail> bridgeOftenCheckDetails = this.bridgeOftenCheckDetailDao.selectList(queryWrapper);
        checkVo.setBridgeDetailList(bridgeOftenCheckDetails);

        List<Accessory> accessories = this.accessoryManager.getAccessoryBySourceId(id);
        checkVo.setAccessories(accessories);
        return checkVo;
    }

    private void saveSiteStatistic(BridgeOftenCheck bridgeOftenCheck){
        SiteStatistic siteStatistic = new SiteStatistic();
        String brigeId = bridgeOftenCheck.getBrigeId();
        BridgeInformation bridge = bridgeInformationManager.getById(brigeId);
        siteStatistic.setRoadSegmentId(bridge.getRoadSegmentId());
        siteStatistic.setRoadSegmentName(bridge.getRoadSegmentName());
        siteStatistic.setCompanyId(bridgeOftenCheck.getCompanyId());
        siteStatistic.setCompanyName(bridgeOftenCheck.getCompanyName());
        siteStatistic.setSiteCode(3);
        siteStatistic.setSiteName("桥梁经常检查");
        Date checkDate = bridgeOftenCheck.getCheckDate();
        String month = new SimpleDateFormat("yyyy-MM").format(checkDate);
        siteStatistic.setAccDateMonth(month);
        String year = new SimpleDateFormat("yyyy").format(checkDate);
        siteStatistic.setAccDateYear(year);
        siteStatistic.setComplete("1");
        siteStatistic.setCompleteNo("0");
        QueryWrapper<SiteStatistic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotEmpty(month),"ACC_DATE_MONTH_",month);
        queryWrapper.eq(StringUtils.isNotEmpty(year),"ACC_DATE_YEAR_",year);
        queryWrapper.eq(StringUtils.isNotEmpty(bridge.getRoadSegmentId()),"ROAD_SEGMENT_ID_",bridge.getRoadSegmentId());
        queryWrapper.eq(StringUtils.isNotEmpty(bridge.getCompanyId()), "COMPANY_ID_", bridge.getCompanyId());
        queryWrapper.eq("SITE_CODE_",3);
        queryWrapper.eq("SITE_NAME_","桥梁经常检查");
        List<SiteStatistic> siteStatistics = siteStatisticDao.selectList(queryWrapper);
        if (siteStatistics.size()>0){
            SiteStatistic statistic = siteStatistics.get(0);
            statistic.setComplete(String.valueOf(Integer.parseInt(statistic.getCompleteNo())+1));
            this.siteStatisticDao.update(siteStatistic,queryWrapper);
        }else {
            siteStatisticDao.insert(siteStatistic);
        }
    }

    @Override
    public void importExcelData(MultipartFile file, BridgeOftenCheck main) {
        Assert.notNull(main, "主数据不能为空");

        try (InputStream inputStream = file.getInputStream();) {
            // 获取数据
            List<BridgeOftenCheckDetail> data = ExcelImportUtil.importExcel(inputStream, BridgeOftenCheckDetail.class, new ImportParams());
            BridgeOftenCheckVo vo = new BridgeOftenCheckVo();
            vo.setBridgeOftenCheck(main);
            vo.setBridgeDetailList(data);
            saveBridgeOftenCheck(vo);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
