package com.artfess.yhxt.budget.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.RoadManager;
import com.artfess.yhxt.basedata.model.Road;
import com.artfess.yhxt.budget.dao.YearBudgetDao;
import com.artfess.yhxt.budget.dao.YearBudgetDetailedDao;
import com.artfess.yhxt.budget.manager.YearBudgetDetailedManager;
import com.artfess.yhxt.budget.manager.YearBudgetManager;
import com.artfess.yhxt.budget.model.YearBudget;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.yhxt.budget.model.YearBudgetDetailed;
import com.artfess.yhxt.budget.model.YearBudgetDetailedLog;
import com.artfess.yhxt.budget.vo.YearBudgetVo;
import com.artfess.yhxt.contract.model.WorkOrderInformation;
import com.artfess.yhxt.specialproject.manager.BizEngineeringProjectManager;
import com.artfess.yhxt.specialproject.model.BizEngineeringProject;
import com.artfess.yhxt.statistics.dao.YearBudgetSumDao;
import com.artfess.yhxt.statistics.model.YearBudgetSum;
import com.artfess.yhxt.statistics.vo.Org4BudgetVO;
import com.artfess.yhxt.statistics.vo.OrgVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 年度总预算表 服务实现类
 *
 * @author xzh
 * @company 阿特菲斯信息技术有限公司
 * @since 2021-08-02
 */
@Service
public class YearBudgetManagerImpl extends BaseManagerImpl<YearBudgetDao, YearBudget> implements YearBudgetManager {
    @Resource
    YearBudgetDetailedDao yearBudgetDetailedDao;
    @Resource
    YearBudgetDetailedManager yearBudgetDetailedManager;
    @Resource
    YearBudgetSumDao yearBudgetSumDao;


    @Resource
    private OrgDao orgDao;

    @Resource
    BaseContext baseContext;

    @Resource
    private RoadManager roadManager;

    @Override
    public List<Org4BudgetVO> getBudgetCount(String year) {
        String orgId ;
        if (StringUtils.isNotEmpty(baseContext.getCurrentOrgId())&&!"0".equals(baseContext.getCurrentOrgId())){
            orgId = baseContext.getCurrentOrgId();
        }else {
            orgId = "1419863231459102720";
        }
        List<Org4BudgetVO> 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){
            Org4BudgetVO fvo = new Org4BudgetVO();
            BeanUtils.copyProperties(org,fvo);
            lists.add(fvo);
        }
        lists = getChild(lists,orgId);


        return this.setCount(lists,year);
    }

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

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

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

    //统计表格
    public Org4BudgetVO newCountWorkOrder(List<String> ids,Org4BudgetVO orgVO,String year) {
        QueryWrapper<YearBudget> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.in("ROAD_SEGMENT_ID_", ids);
        orderQueryWrapper.eq("IS_DELE_",0);
        orderQueryWrapper.eq("ASCRIPTION_YEAR_",year);
        orgVO.setAscriptionYear(Integer.valueOf(year));
        List<YearBudget> list = this.list(orderQueryWrapper);
        if (list.size()>0){
            orgVO.setBudgetSum(list.stream().map(p -> p.getBudgetSum())
                    .reduce(BigDecimal.ZERO, (b1, b2) -> b1.add(b2)));

            orgVO.setAlreadyCount(list.stream().map(p -> p.getAlreadyCount())
                    .reduce(BigDecimal.ZERO, (b1, b2) -> b1.add(b2)));

            if ("4".equals(orgVO.getGrade())){
                orgVO.setRoadSegmentId(list.get(0).getRoadSegmentId());
            }

        }else {
            orgVO.setBudgetSum(new BigDecimal("0"));

            orgVO.setAlreadyCount(new BigDecimal("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<Org4BudgetVO> getChild(List<Org4BudgetVO> allList, String pCode) {
        List<Org4BudgetVO> returnList = new ArrayList<>();
        for (Org4BudgetVO entity : allList){
            if (pCode.equals(entity.getParentId())) {
                entity.setChirldren(getChild(allList, entity.getId()));
                returnList.add(entity);
            }
        }
        return returnList;
    }

    @Override
    public void checkYear(YearBudget yearBudget) {
        QueryWrapper<YearBudget> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(yearBudget.getId())) {
            queryWrapper.notIn("ID_", yearBudget.getId());
        }
        queryWrapper.eq("ASCRIPTION_YEAR_", yearBudget.getAscriptionYear());
        queryWrapper.eq("IS_DELE_", "0");
        queryWrapper.eq("COMPANY_ID_", yearBudget.getCompanyId());
        queryWrapper.eq("ROAD_SEGMENT_ID_", yearBudget.getRoadSegmentId());
        List<YearBudget> list = baseMapper.selectList(queryWrapper);
        if (list.size() > 0) {
            throw new RuntimeException("该年份预算已经添加");
        }
    }

    @Override
    public YearBudget getYearBudgetById(String id) {
        return this.baseMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateYear(BigDecimal bigDecimal, Integer ascriptionYear) {
        UpdateWrapper<YearBudget> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("ASCRIPTION_YEAR_", ascriptionYear);
        updateWrapper.set("BUDGET_SUM_", bigDecimal);
        this.baseMapper.update(null, updateWrapper);
    }

    @Override
    public PageList<YearBudget> queryYearBuget(QueryFilter<YearBudget> queryFilter) {
        IPage<YearBudget> result = baseMapper.queryYearBuget(convert2IPage(queryFilter.getPageBean()), convert2Wrapper(queryFilter, currentModelClass()));

        return new PageList<>(result);
    }

    @Override
    public YearBudgetVo getYearBudgetVoById(String id) {
        YearBudgetVo yearBudgetVo = new YearBudgetVo();
        YearBudget yearBudget = this.getById(id);
        yearBudgetVo.setYearBudget(yearBudget);
        QueryWrapper<YearBudgetDetailed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("YEAR_BUDGET_ID_", id);
        queryWrapper.eq("IS_DELE_", "0");
        queryWrapper.orderByAsc("SORT_");
        List<YearBudgetDetailed> list = this.yearBudgetDetailedDao.selectList(queryWrapper);
        if (list.size() > 0) {
            yearBudgetVo.setYearBudgetDetaileds(list);
        }
        return yearBudgetVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveYearBudgetVo(YearBudgetVo yearBudgetVo) {

        YearBudget yearBudget = yearBudgetVo.getYearBudget();
        if (yearBudget.getAscriptionYear() == null) {
            throw new RuntimeException("请填写对应的年份");
        }
        if (yearBudget != null) {
            yearBudget.setIsDele("0");
            yearBudget.setAlreadyCount(new BigDecimal("0.00"));
            this.save(yearBudget);
            synchronizationBudget(yearBudget);
            List<YearBudgetDetailed> detailedList = yearBudgetVo.getYearBudgetDetaileds();
            if (detailedList.size() > 0) {
                for (YearBudgetDetailed yearBudgetDetailed : detailedList) {
                    yearBudgetDetailed.setYearBudgetId(yearBudget.getId());
                    yearBudgetDetailed.setIsDele("0");
                    yearBudgetDetailed.setImageProgress(new BigDecimal("0.00"));
                }
                this.yearBudgetDetailedManager.saveBatch(detailedList);
            }
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateYearBudgetVo(YearBudgetVo yearBudgetVo) {
        YearBudget yearBudget = yearBudgetVo.getYearBudget();
        if (yearBudget != null) {

            List<YearBudgetDetailed> detailedList = yearBudgetVo.getYearBudgetDetaileds();
            if (detailedList.size() > 0) {
                for (YearBudgetDetailed yearBudgetDetailed : detailedList) {
                    yearBudgetDetailed.setYearBudgetId(yearBudget.getId());
                    yearBudgetDetailed.setIsDele("0");
                    BigDecimal imageProgress = detailedList.stream().filter(s -> s != null && s.getImageProgress() != null).map(YearBudgetDetailed::getImageProgress)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    yearBudget.setAlreadyCount(imageProgress);
                }
                this.yearBudgetDetailedManager.saveOrUpdateBatch(detailedList);
                this.update(yearBudget);
                synchronizationBudget(yearBudget);
            }
        }
    }

    @Async
    public void synchronizationBudget(YearBudget yearBudget) {
        QueryWrapper<YearBudgetSum> yearBudgetSumQueryWrapper = new QueryWrapper<>();
        yearBudgetSumQueryWrapper.eq("ACC_DATE_YEAR_", yearBudget.getAscriptionYear());
        yearBudgetSumQueryWrapper.eq("ROAD_SEGMENT_ID_", yearBudget.getRoadSegmentId());
        YearBudgetSum yearBudgetSum = this.yearBudgetSumDao.selectOne(yearBudgetSumQueryWrapper);

        if (null == yearBudgetSum) {
            yearBudgetSum = new YearBudgetSum();
            yearBudgetSum.setAccDateYear(yearBudget.getAscriptionYear());
            yearBudgetSum.setRoadSegmentId(yearBudget.getRoadSegmentId());
            yearBudgetSum.setRoadSegmentName(yearBudget.getRoadSegmentName());
            yearBudgetSum.setCompanyId(yearBudget.getCompanyId());
            yearBudgetSum.setCompanyName(yearBudget.getCompanyName());
            if (yearBudget.getBudgetSum() != null) {
                yearBudgetSum.setBudgetSum(yearBudget.getBudgetSum().toString());
            }
            this.yearBudgetSumDao.insert(yearBudgetSum);
        } else {
            if (yearBudget.getBudgetSum() != null) {
//                BigDecimal budgetSum = yearBudget.getBudgetSum();
                yearBudgetSum.setBudgetSum(yearBudget.getBudgetSum().toString());
            }
            this.yearBudgetSumDao.updateById(yearBudgetSum);
        }


    }
}
