package com.dsk.cscec.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsk.common.exception.ServiceException;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.CbQuantitySummaryActual;
import com.dsk.cscec.domain.CbSubject;
import com.dsk.cscec.domain.bo.CbProjectBaseBo;
import com.dsk.cscec.domain.bo.CbQuantitySummaryListBo;
import com.dsk.cscec.domain.vo.CbQuantitySummaryListVo;
import com.dsk.cscec.mapper.CbQuantitySummaryMapper;
import com.dsk.cscec.mapper.CbSubjectMapper;
import com.dsk.cscec.service.ICbQuantitySummaryActualService;
import com.dsk.cscec.service.ICbQuantitySummaryService;
import jodd.bean.BeanException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 成本-工料汇总基本表(CbQuantitySummary)表服务实现类
 *
 * @author lcl
 * @since 2024-02-05 11:06:56
 */
@Slf4j
@Service
public class CbQuantitySummaryServiceImpl extends ServiceImpl<CbQuantitySummaryMapper, CbQuantitySummary> implements ICbQuantitySummaryService {

    @Autowired
    private ICbQuantitySummaryActualService baseActualService;
    @Resource
    private CbSubjectMapper cbSubjectMapper;

    @Override
    public List<Map<String, Object>> subjectTree(CbProjectBaseBo bo) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> list = baseMapper.selectSubject(bo);
        if (!ObjectUtils.isEmpty(list)) {
            Map<String, Map<String, Map<String, List<Map<String, Object>>>>> map = list.stream()
                    .collect(
                            Collectors.groupingBy(item -> item.get("one").toString(),
                                    Collectors.groupingBy(item -> item.get("two").toString(),
                                            Collectors.groupingBy(item -> item.get("three").toString()))));
            Map<String, Object> resMap = new HashMap<>();
            List<Map<String, Object>> resList = new ArrayList<>();
            resMap.put("name", "房建类成本科目");
            resMap.put("sort", 1);
            for (Map.Entry<String, Map<String, Map<String, List<Map<String, Object>>>>> entry : map.entrySet()) {
                Map<String, Object> oneMap = new HashMap<>();
                List<Map<String, Object>> oneList = new ArrayList<>();
                oneMap.put("name", entry.getKey());
                oneMap.put("sort", cbSubjectMapper.selectOne(Wrappers.<CbSubject>lambdaQuery().eq(CbSubject::getCbSubjectName,entry.getKey())).getSort());
                for (Map.Entry<String, Map<String, List<Map<String, Object>>>> twoEntry : entry.getValue().entrySet()) {
                    Map<String, Object> twoMap = new HashMap<>();
                    List<Map<String, Object>> twoList = new ArrayList<>();
                    twoMap.put("name", twoEntry.getKey());
                    for (Map.Entry<String, List<Map<String, Object>>> threeEntry : twoEntry.getValue().entrySet()) {
                        Map<String, Object> threeMap = new HashMap<>();
                        threeMap.put("name", threeEntry.getKey());
                        twoList.add(threeMap);
                    }
                    twoMap.put("children", twoList);
                    oneList.add(twoMap);
                }
                oneMap.put("children", oneList);
                resList.add(oneMap);
            }
            resMap.put("children", resList);
            resultList.add(resMap);
        }

        int otherSubjectCount = baseMapper.selectOtherSubjectCount(bo);
        if (otherSubjectCount > 0) {
            Map<String, Object> resMap = new HashMap<>();
            resMap.put("name", "未归类项目");
            resMap.put("sort", 2);
            resultList.add(resMap);
        }
        return resultList;
    }

    @Override
    public List<String> monthList(CbQuantitySummaryListBo bo) {
        return baseMapper.selectMonthList(bo);
    }

    @Override
    public List<CbQuantitySummaryListVo> subjectList(CbQuantitySummaryListBo bo) {
        return baseMapper.selectListBySubject(bo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateActual(List<CbQuantitySummaryActual> list) {
        if (ObjectUtils.isEmpty(list)) throw new BeanException("数据不能为空");
        for (CbQuantitySummaryActual actual : list) {
            if (ObjectUtils.isEmpty(actual.getCbQuantitySummaryId())) throw new BeanException("基础数据id不能为空！");
            if (ObjectUtils.isEmpty(actual.getQuantities())) throw new BeanException("工程量（本月用料）不能为空！");
            if (ObjectUtils.isEmpty(actual.getRecordDate())) throw new BeanException("填写月份不能为空！");
            actual.setId(ObjectUtils.isEmpty(actual.getId()) ? SecureUtil.md5(actual.getCbQuantitySummaryId() + actual.getRecordDate()) : actual.getId());
            boolean b = baseActualService.saveOrUpdate(actual);
            if (!b) {
                log.error("CbQuantitySummaryServiceImpl.updateActual() data insert error! data:" + JSONUtil.toJsonStr(actual));
                throw new ServiceException("数据添加错误！");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushData(CbQuantitySummaryActual bo) {
        //数据记录
        if (ObjectUtils.isEmpty(bo.getId())) throw new BeanException("id不能为空！");
        if (ObjectUtils.isEmpty(bo.getPushQuantities())) throw new BeanException("推送工程量不能为空！");
        if (ObjectUtils.isEmpty(bo.getIpmProjectCode())) throw new BeanException("IPM项目编码不能为空！");
        if (ObjectUtils.isEmpty(bo.getIpmContractCode())) throw new BeanException("IPM合同编码不能为空！");
        if (ObjectUtils.isEmpty(bo.getIpmBizCode())) throw new BeanException("IPM作业编码不能为空！");
        boolean update = baseActualService.updateById(bo);
        if (!update) {
            log.error("CbQuantitySummaryServiceImpl.pushData() data update error! data:" + JSONUtil.toJsonStr(bo));
            throw new ServiceException("数据添加错误！");
        }
        //TODO 推送数据

    }
}

