package com.unis.base.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.unis.base.common.vo.CcsstzjsmxVO;
import com.unis.base.server.dao.CcsstzjsmxDao;
import com.unis.base.server.entity.CcsbtzjsmxDO;
import com.unis.base.server.entity.CcsstzjsmxDO;
import com.unis.base.server.service.CcsstzjsmxService;
import com.unis.base.server.service.OrgainzeService;
import com.unis.common.utils.CurrentUtil;
import com.unis.common.utils.ResponseWrapper;
import com.unis.user.common.vo.org.OrgainzeVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.persistence.Column;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @Classname CcsstzjsmxServiceImpl
 * @Description 仓储设施投资建设明细
 * @Date 2024/1/2 10:51
 * @Created by rising123sun
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class CcsstzjsmxServiceImpl implements CcsstzjsmxService {

    @Resource
    private OrgainzeService orgainzeService;

    @Resource
    private CcsstzjsmxDao ccsstzjsmxDao;


    @Override
    public ResponseWrapper add(CcsstzjsmxDO ccsstzjsmxDO) {
        // 查询所填年度的当前机构是否已经填报，如果已经填报，不允许再次填报
        CcsstzjsmxDO ccsstzjsmxDO1 = ccsstzjsmxDao.queryBySbnfAndOrgCode(ccsstzjsmxDO.getSbnf(), ccsstzjsmxDO.getOrgCode());
        if (null != ccsstzjsmxDO1) {
            return ResponseWrapper.error("该年度已经存在待提交或已上报数据，不允许重复填报!");
        }
        if (StringUtils.isNotBlank(ccsstzjsmxDO.getSbzt()) && "1".equals(ccsstzjsmxDO.getSbzt())) {
            // 如果是直接上报，设置下上报时间
            ccsstzjsmxDO.setSbsj(new Date());
        }
        CcsstzjsmxDO.buildData(ccsstzjsmxDO);
        ccsstzjsmxDao.insert(ccsstzjsmxDO);
        return ResponseWrapper.success("新增成功！");
    }

    @Override
    public CcsstzjsmxDO queryLastYearData(String sbnf, String orgCode) {
        CcsstzjsmxDO ccsstzjsmxDO = ccsstzjsmxDao.queryBySbnfAndOrgCode(sbnf, orgCode);
        if (null == ccsstzjsmxDO) {
            ccsstzjsmxDO = new CcsstzjsmxDO();
        }
        CcsstzjsmxDO.buildData(ccsstzjsmxDO);
        return ccsstzjsmxDO;
    }

    public List<CcsstzjsmxDO> queryLastYearDataForList(String sbnf, String orgCode) {
        return ccsstzjsmxDao.queryLastYearDataForList(sbnf, orgCode);
    }

    @Override
    public ResponseWrapper update(CcsstzjsmxDO ccsstzjsmxDO) {
        // 查询所填年度的当前机构是否已经填报，如果已经填报，不允许再次填报
        CcsstzjsmxDO ccsstzjsmxDO1 = ccsstzjsmxDao.queryBySbnfAndOrgCode(ccsstzjsmxDO.getSbnf(), ccsstzjsmxDO.getOrgCode());
        if (null != ccsstzjsmxDO1 && !ccsstzjsmxDO.getId().equals(ccsstzjsmxDO1.getId())) {
            return ResponseWrapper.error("该年度已经存在待提交或已上报数据，不允许重复填报!");
        }
        if (StringUtils.isNotBlank(ccsstzjsmxDO.getSbzt()) && "1".equals(ccsstzjsmxDO.getSbzt())) {
            // 如果是直接上报，设置下上报时间
            ccsstzjsmxDO.setSbsj(new Date());
        }
        CcsstzjsmxDO.buildData(ccsstzjsmxDO);
        ccsstzjsmxDao.updateByPrimaryKeySelective(ccsstzjsmxDO);
        return ResponseWrapper.success("修改成功！");
    }

    @Override
    public PageInfo<CcsstzjsmxVO> queryPageList(Integer pageSize, Integer pageNum, CcsstzjsmxVO ccsstzjsmxVO) {
        PageHelper.startPage(pageNum, pageSize);
        List<CcsstzjsmxVO> list = ccsstzjsmxDao.queryPageList(ccsstzjsmxVO);
        return new PageInfo<>(list);
    }

    @Override
    public ResponseWrapper queryDetail(String id) {
        CcsstzjsmxDO ccsstzjsmxDO = ccsstzjsmxDao.selectByPrimaryKey(id);
        Map<String, CcsstzjsmxDO> result = new HashMap<>();
        if (null != ccsstzjsmxDO) {
            CcsstzjsmxDO.buildData(ccsstzjsmxDO);
            result.put("bndsj", ccsstzjsmxDO);
            String synd = String.valueOf(Integer.parseInt(ccsstzjsmxDO.getSbnf()) - 1);
            CcsstzjsmxDO syndsj = queryLastYearData(synd, ccsstzjsmxDO.getOrgCode());
            result.put("syndsj", syndsj);
            // 同比增减为本年度每一项数据减去上一年度相同项数据
            CcsstzjsmxDO tbzjsj = new CcsstzjsmxDO();
            setTbzjValue(tbzjsj, ccsstzjsmxDO, syndsj);
            result.put("tbzjsj", tbzjsj);
        } else {
            CcsstzjsmxDO ccsstzjsmxDO1 = new CcsstzjsmxDO();
            CcsstzjsmxDO.buildData(ccsstzjsmxDO);
            result.put("bndsj", ccsstzjsmxDO1);
            result.put("syndsj", ccsstzjsmxDO1);
            result.put("tbzjsj", ccsstzjsmxDO1);
        }
        return ResponseWrapper.success(result);
    }

    @Override
    public Map<String, CcsstzjsmxDO> queryHzForGlOrGxgs(CcsstzjsmxVO ccsstzjsmxVO) {
        Map<String, CcsstzjsmxDO> result = new HashMap<>();
        Example example = new Example(CcsstzjsmxDO.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(ccsstzjsmxVO.getSbnf())) {
            criteria.andEqualTo("sbnf", ccsstzjsmxVO.getSbnf());
        }
        if (StringUtils.isNotBlank(ccsstzjsmxVO.getOrgCode())) {
            criteria.andLike("orgCode", ccsstzjsmxVO.getOrgCode() + "%");
        }
        // 上报状态
        if (StringUtils.isNotBlank(ccsstzjsmxVO.getSbzt())) {
            criteria.andEqualTo("sbzt", "1");
        }
        List<CcsstzjsmxDO> ccsstzjsmxDOList = ccsstzjsmxDao.selectByExample(example);
        if (null != ccsstzjsmxDOList && ccsstzjsmxDOList.size() > 0) {
            CcsstzjsmxDO bndsj = qhtj(ccsstzjsmxDOList);
            bndsj.setSbnf(ccsstzjsmxVO.getSbnf());
            result.put("bndsj", bndsj);

        } else {
            CcsstzjsmxDO ccsstzjsmxDO = new CcsstzjsmxDO();
            CcsstzjsmxDO.buildData(ccsstzjsmxDO);
            ccsstzjsmxDO.setSbnf(ccsstzjsmxVO.getSbnf());
            result.put("bndsj", ccsstzjsmxDO);
        }
        String synd = String.valueOf(Integer.parseInt(ccsstzjsmxVO.getSbnf()) - 1);
        List<CcsstzjsmxDO> ccsstzjsmxDOList1 = queryLastYearDataForList(synd, ccsstzjsmxVO.getOrgCode());
        CcsstzjsmxDO syndsj = qhtj(ccsstzjsmxDOList1);
        result.put("syndsj", syndsj);
        // 同比增减为本年度每一项数据减去上一年度相同项数据
        CcsstzjsmxDO tbzjsj = new CcsstzjsmxDO();
        setTbzjValue(tbzjsj, result.get("bndsj"), syndsj);
        result.put("tbzjsj", tbzjsj);
        return result;
    }

    @Override
    public List<CcsstzjsmxDO> queryMxForQlbOrGxgs(CcsstzjsmxVO ccsstzjsmxVO) {
        OrgainzeVO organization = orgainzeService.getOrganization();
        OrgainzeVO organization1 = getOrganization(ccsstzjsmxVO.getOrgCode(), organization);
        List<CcsstzjsmxDO> result = new ArrayList<>();
        if (null != organization1) {
            // 获取organization1和他的子节点以及子节点的子节点的orgName
            List<String> orgNameList = getOrgNameList(organization1);
            // 把自己去掉
            orgNameList.remove(organization1.getOrgName());
            String sbnf = ccsstzjsmxVO.getSbnf();
            Example example = new Example(CcsstzjsmxDO.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("sbnf", sbnf);
            criteria.andEqualTo("sbzt", "1");
            List<CcsstzjsmxDO> ccsstzjsmxDOList = ccsstzjsmxDao.selectByExample(example);
            // 将orgNameList和ccsstzjsmxDOList进行匹配，如果ccsstzjsmxDOList中的sskdmc包含在orgNameList中，则将该条数据放入到result中
            // orgNameList不在ccsbtzjsmxDOList中的数据，放入到另一个集合中，进行下一步处理

            for (String orgName : orgNameList) {
                boolean flag = false;
                for (CcsstzjsmxDO ccsstzjsmxDO : ccsstzjsmxDOList) {
                    if (ccsstzjsmxDO.getSskdmc().contains(orgName)) {
                        ccsstzjsmxDO.setSbzt("已上报");
                        result.add(ccsstzjsmxDO);
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    CcsstzjsmxDO ccsstzjsmxDO = new CcsstzjsmxDO();
                    ccsstzjsmxDO.setSskdmc(orgName);
                    ccsstzjsmxDO.setSbzt("未上报");
                    ccsstzjsmxDO.setSbnf(sbnf);
                    CcsstzjsmxDO.buildData(ccsstzjsmxDO);
                    result.add(ccsstzjsmxDO);
                }
            }

        }
        // 最后增加一个合计行
        CcsstzjsmxDO hj = qhtj(result);
        hj.setSskdmc("合计");
        hj.setBz("合计");
        result.add(hj);
        return result;
    }

    @Override
    public Map<String, List<CcsstzjsmxDO>> queryMxForSj(CcsstzjsmxVO ccsstzjsmxVO) {
        if (CurrentUtil.getOrgId().equals("LS001")) {
            // 市局查看
            OrgainzeVO organization = orgainzeService.getOrganization();
            // 把organization的children的orgName为和平区发改委，河东区发改委，河西区发改委，南开区发改委,河北区发改委，红桥区发改委剔除掉
            List<OrgainzeVO> children = organization.getChildren();
            List<OrgainzeVO> children1 = new ArrayList<>();
            for (OrgainzeVO orgainzeVO : children) {
                if (!"和平区发改委".equals(orgainzeVO.getOrgName()) && !"河东区发改委".equals(orgainzeVO.getOrgName()) && !"河西区发改委".equals(orgainzeVO.getOrgName()) && !"南开区发改委".equals(orgainzeVO.getOrgName()) && !"河北区发改委".equals(orgainzeVO.getOrgName()) && !"红桥区发改委".equals(orgainzeVO.getOrgName())) {
                    children1.add(orgainzeVO);
                }
            }
            organization.setChildren(children1);
            Map<String, List<CcsstzjsmxDO>> result = new LinkedHashMap<>();
            if (organization.getChildren().size() > 0) {
                for (OrgainzeVO child : organization.getChildren()) {
                    CcsstzjsmxVO ccsstzjsmxVO1 = new CcsstzjsmxVO();
                    ccsstzjsmxVO1.setSbnf(ccsstzjsmxVO.getSbnf());
                    ccsstzjsmxVO1.setOrgCode(child.getOrgCode());
                    List<CcsstzjsmxDO> ccsstzjsmxDOList = queryMxForQlbOrGxgs(ccsstzjsmxVO1);
                    // 把合计行去掉
                    ccsstzjsmxDOList.remove(ccsstzjsmxDOList.size() - 1);
                    if (child.getOrgName().equals("天津市粮食储备有限公司")) {
                        result.put("异地库", ccsstzjsmxDOList);
                    } else {
                        // 如果包含发改委三个字，就截取掉
                        if (child.getOrgName().contains("发改委")) {
                            result.put(child.getOrgName().replace("发改委", ""), ccsstzjsmxDOList);
                        } else {
                            result.put(child.getOrgName(), ccsstzjsmxDOList);
                        }
                    }
                }
            }
            // 进行筛选条件的过滤
            if (StringUtils.isNotBlank(ccsstzjsmxVO.getSsqymc())) {
                Iterator<Map.Entry<String, List<CcsstzjsmxDO>>> iterator = result.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, List<CcsstzjsmxDO>> next = iterator.next();
                    if (!next.getKey().contains(ccsstzjsmxVO.getSsqymc())) {
                        iterator.remove();
                    }
                }
            }
            // 所属库点
            if (StringUtils.isNotBlank(ccsstzjsmxVO.getSskdmc())) {
                Iterator<Map.Entry<String, List<CcsstzjsmxDO>>> iterator = result.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, List<CcsstzjsmxDO>> next = iterator.next();
                    List<CcsstzjsmxDO> value = next.getValue();
                    Iterator<CcsstzjsmxDO> iterator1 = value.iterator();
                    while (iterator1.hasNext()) {
                        CcsstzjsmxDO next1 = iterator1.next();
                        if (!next1.getSskdmc().contains(ccsstzjsmxVO.getSskdmc())) {
                            iterator1.remove();
                        }
                    }
                    if (value.size() == 0) {
                        iterator.remove();
                    }
                }
            }
            // 返回
            return result;
        }
        return null;
    }

    // 根据当前企业的orgCode查询相关层级的OrgainzeVO
    public OrgainzeVO getOrganization(String orgCode, OrgainzeVO organization) {
        // 判断当前orgCode是否是当前企业的orgCode,如果是则返回
        if (organization.getOrgCode().equals(orgCode)) {
            return organization;
        } else {
            // 逐级遍历children
            List<OrgainzeVO> children = organization.getChildren();
            for (OrgainzeVO orgainzeVO : children) {
                OrgainzeVO result = getOrganization(orgCode, orgainzeVO);
                if (result != null) {
                    // 如果找到匹配的节点，返回该节点
                    return result;
                }
            }
            // 如果所有子节点都不匹配，返回null
            return null;
        }
    }

    // 递归获取OrgainzeVO以及他的所有子节点的orgName
    public List<String> getOrgNameList(OrgainzeVO organization) {
        List<String> orgNameList = new ArrayList<>();
        addOrgNames(organization, orgNameList);
        return orgNameList;
    }

    private void addOrgNames(OrgainzeVO organization, List<String> orgNameList) {
        orgNameList.add(organization.getOrgName());
        List<OrgainzeVO> children = organization.getChildren();
        for (OrgainzeVO orgainzeVO : children) {
            addOrgNames(orgainzeVO, orgNameList); // 直接将子节点的名称添加到同一个列表
        }
    }

    // 同比增减设置值的方法
    public void setTbzjValue(CcsstzjsmxDO tbzj, CcsstzjsmxDO bnd, CcsstzjsmxDO synd) {
        tbzj.setXmztBddxkgxm(bnd.getXmztBddxkgxm() - (synd.getXmztBddxkgxm()));
        tbzj.setXmztBndjgxm(bnd.getXmztBndjgxm() - (synd.getXmztBndjgxm()));
        tbzj.setXmztNdmzjxm(bnd.getXmztNdmzjxm() - (synd.getXmztNdmzjxm()));
        tbzj.setNdwctzAxmlx(bnd.getNdwctzAxmlx().subtract(synd.getNdwctzAxmlx()));
        tbzj.setNdwctzXjgbzlc(bnd.getNdwctzXjgbzlc().subtract(synd.getNdwctzXjgbzlc()));
        tbzj.setNdwctzJcsjgz(bnd.getNdwctzJcsjgz().subtract(synd.getNdwctzJcsjgz()));
        tbzj.setNdwctzGrxn(bnd.getNdwctzGrxn().subtract(synd.getNdwctzGrxn()));
        tbzj.setNdwctzQmxn(bnd.getNdwctzQmxn().subtract(synd.getNdwctzQmxn()));
        tbzj.setNdwctzTfjs(bnd.getNdwctzTfjs().subtract(synd.getNdwctzTfjs()));
        tbzj.setNdwctzKwjs(bnd.getNdwctzKwjs().subtract(synd.getNdwctzKwjs()));
        tbzj.setNdwctzLqck(bnd.getNdwctzLqck().subtract(synd.getNdwctzLqck()));
        tbzj.setNdwctzSccs(bnd.getNdwctzSccs().subtract(synd.getNdwctzSccs()));
        tbzj.setNdwctzXswx(bnd.getNdwctzXswx().subtract(synd.getNdwctzXswx()));
        tbzj.setNdwctzQt(bnd.getNdwctzQt().subtract(synd.getNdwctzQt()));
        tbzj.setNdwctzAtzly(bnd.getNdwctzAtzly().subtract(synd.getNdwctzAtzly()));
        tbzj.setNdwctzZycz(bnd.getNdwctzZycz().subtract(synd.getNdwctzZycz()));
        tbzj.setNdwctzSjcz(bnd.getNdwctzSjcz().subtract(synd.getNdwctzSjcz()));
        tbzj.setNdwctzQjcz(bnd.getNdwctzQjcz().subtract(synd.getNdwctzQjcz()));
        tbzj.setNdwctzQyzc(bnd.getNdwctzQyzc().subtract(synd.getNdwctzQyzc()));
        tbzj.setNdwctzQt2(bnd.getNdwctzQt2().subtract(synd.getNdwctzQt2()));
        tbzj.setNdwctze(bnd.getNdwctze().subtract(synd.getNdwctze()));
        tbzj.setSjcfs(bnd.getSjcfs() - synd.getSjcfs());
        tbzj.setSjcrs(bnd.getSjcrs().subtract(synd.getSjcrs()));
        tbzj.setSjajs(bnd.getSjajs() - synd.getSjajs());
        CcsstzjsmxDO.buildData(tbzj);
    }

    // 求和
    public CcsstzjsmxDO qhtj(List<CcsstzjsmxDO> list) {
        CcsstzjsmxDO ccsstzjsmxDO = new CcsstzjsmxDO();
        if (null != list && list.size() > 0) {
            ccsstzjsmxDO.setXmztBddxkgxm(list.stream().mapToInt(CcsstzjsmxDO::getXmztBddxkgxm).sum());
            ccsstzjsmxDO.setXmztBndjgxm(list.stream().mapToInt(CcsstzjsmxDO::getXmztBndjgxm).sum());
            ccsstzjsmxDO.setXmztNdmzjxm(list.stream().mapToInt(CcsstzjsmxDO::getXmztNdmzjxm).sum());
            ccsstzjsmxDO.setNdwctzAxmlx(list.stream().map(CcsstzjsmxDO::getNdwctzAxmlx).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzXjgbzlc(list.stream().map(CcsstzjsmxDO::getNdwctzXjgbzlc).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzJcsjgz(list.stream().map(CcsstzjsmxDO::getNdwctzJcsjgz).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzGrxn(list.stream().map(CcsstzjsmxDO::getNdwctzGrxn).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzQmxn(list.stream().map(CcsstzjsmxDO::getNdwctzQmxn).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzTfjs(list.stream().map(CcsstzjsmxDO::getNdwctzTfjs).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzKwjs(list.stream().map(CcsstzjsmxDO::getNdwctzKwjs).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzLqck(list.stream().map(CcsstzjsmxDO::getNdwctzLqck).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzSccs(list.stream().map(CcsstzjsmxDO::getNdwctzSccs).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzXswx(list.stream().map(CcsstzjsmxDO::getNdwctzXswx).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzQt(list.stream().map(CcsstzjsmxDO::getNdwctzQt).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzAtzly(list.stream().map(CcsstzjsmxDO::getNdwctzAtzly).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzZycz(list.stream().map(CcsstzjsmxDO::getNdwctzZycz).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzSjcz(list.stream().map(CcsstzjsmxDO::getNdwctzSjcz).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzQjcz(list.stream().map(CcsstzjsmxDO::getNdwctzQjcz).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzQyzc(list.stream().map(CcsstzjsmxDO::getNdwctzQyzc).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctzQt2(list.stream().map(CcsstzjsmxDO::getNdwctzQt2).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setNdwctze(list.stream().map(CcsstzjsmxDO::getNdwctze).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setSjcfs(list.stream().mapToInt(CcsstzjsmxDO::getSjcfs).sum());
            ccsstzjsmxDO.setSjcrs(list.stream().map(CcsstzjsmxDO::getSjcrs).reduce(BigDecimal.ZERO, BigDecimal::add));
            ccsstzjsmxDO.setSjajs(list.stream().mapToInt(CcsstzjsmxDO::getSjajs).sum());
            CcsstzjsmxDO.buildData(ccsstzjsmxDO);
        } else {
            CcsstzjsmxDO ccsstzjsmxDO1 = new CcsstzjsmxDO();
            CcsstzjsmxDO.buildData(ccsstzjsmxDO1);
            ccsstzjsmxDO = ccsstzjsmxDO1;
        }
        return ccsstzjsmxDO;
    }


}
