package com.jjt.calc.service.impl;

import com.jjt.calc.domain.TwinCalcDayYhj;
import com.jjt.calc.domain.TwinCalcHourYhj;
import com.jjt.calc.mapper.TwinCalcDayYhjMapper;
import com.jjt.calc.mapper.TwinCalcHourYhjMapper;
import com.jjt.calc.service.ITwinCalcDayYhjService;
import com.jjt.common.utils.DateUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 印花机日统计数据Service业务层处理
 *
 * @author wukai
 * @date 2025-03-07
 */
@Service
public class TwinCalcDayYhjServiceImpl implements ITwinCalcDayYhjService {
    @Resource
    private TwinCalcDayYhjMapper twinCalcDayYhjMapper;
    @Resource
    private TwinCalcHourYhjMapper hourYhjMapper;
    @Resource
    private SqlSessionFactory factory;

    /**
     * 查询印花机日统计数据
     *
     * @param id 印花机日统计数据主键
     * @return 印花机日统计数据
     */
    @Override
    public TwinCalcDayYhj selectTwinCalcDayYhjById(Long id) {
        return twinCalcDayYhjMapper.selectTwinCalcDayYhjById(id);
    }

    /**
     * 查询印花机日统计数据列表
     *
     * @param twinCalcDayYhj 印花机日统计数据
     * @return 印花机日统计数据
     */
    @Override
    public List<TwinCalcDayYhj> selectTwinCalcDayYhjList(TwinCalcDayYhj twinCalcDayYhj) {
        return twinCalcDayYhjMapper.selectTwinCalcDayYhjList(twinCalcDayYhj);
    }

    /**
     * 新增印花机日统计数据
     *
     * @param twinCalcDayYhj 印花机日统计数据
     * @return 结果
     */
    @Override
    public int insertTwinCalcDayYhj(TwinCalcDayYhj twinCalcDayYhj) {
        return twinCalcDayYhjMapper.insertTwinCalcDayYhj(twinCalcDayYhj);
    }

    /**
     * 修改印花机日统计数据
     *
     * @param twinCalcDayYhj 印花机日统计数据
     * @return 结果
     */
    @Override
    public int updateTwinCalcDayYhj(TwinCalcDayYhj twinCalcDayYhj) {
        return twinCalcDayYhjMapper.updateTwinCalcDayYhj(twinCalcDayYhj);
    }

    /**
     * 批量删除印花机日统计数据
     *
     * @param ids 需要删除的印花机日统计数据主键
     * @return 结果
     */
    @Override
    public int deleteTwinCalcDayYhjByIds(Long[] ids) {
        return twinCalcDayYhjMapper.deleteTwinCalcDayYhjByIds(ids);
    }

    /**
     * 删除印花机日统计数据信息
     *
     * @param id 印花机日统计数据主键
     * @return 结果
     */
    @Override
    public int deleteTwinCalcDayYhjById(Long id) {
        return twinCalcDayYhjMapper.deleteTwinCalcDayYhjById(id);
    }

    /**
     * 统计指定日期的数据
     * 需要统计2种类型，1.按班组统计 2.按自然日统计
     *
     * @param localDate 日期
     */
    @Override
    public void day(LocalDate localDate) {
        //先删除当前日期数据
        twinCalcDayYhjMapper.delete4date(localDate.toString());
        //1.先按班组统计
        TwinCalcHourYhj search = new TwinCalcHourYhj();
        Map<String, Object> params = new HashMap<>(16);
        LocalDateTime st = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(7);
        LocalDateTime ed = st.plusHours(23);
        params.put("sTime", DateUtils.toDate(st));
        params.put("eTime", DateUtils.toDate(ed));
        search.setParams(params);
        List<TwinCalcHourYhj> list = hourYhjMapper.selectTwinCalcHourYhjList(search);
        //设置班组
        list.forEach(TwinCalcHourYhj::setTeam);
        //先按ID分组
        Map<Integer, List<TwinCalcHourYhj>> calcMap = list.stream().collect(Collectors.groupingBy(TwinCalcHourYhj::getDeviceId, LinkedHashMap::new, Collectors.toList()));
        Map<Integer, TwinCalcDayYhj> resultMap = new HashMap<>(16);
        for (Integer deviceId : calcMap.keySet()) {
            //按班组统计
            Map<String, Integer> calcTeam = calcMap.get(deviceId).stream().collect(Collectors.groupingBy(TwinCalcHourYhj::getTeam, Collectors.reducing(0, TwinCalcHourYhj::getLength, Integer::sum)));
            TwinCalcDayYhj calc = new TwinCalcDayYhj();
            calc.setDeviceId(deviceId);
            calc.setTime(DateUtils.toDate(localDate));
            calc.setLength(calcTeam.get("A"), calcTeam.get("B"));
            resultMap.put(deviceId, calc);
        }

        //按自然日统计
        search = new TwinCalcHourYhj();
        params = new HashMap<>(16);
        params.put("beginDataDate", localDate.toString());
        params.put("endDataDate", localDate.toString());
        search.setParams(params);
        list = hourYhjMapper.selectTwinCalcHourYhjList(search);
        List<TwinCalcDayYhj> yhjList = new ArrayList<>();
        //按ID分组统计
        Map<Integer, Integer> calcDay = list.stream().collect(Collectors.groupingBy(TwinCalcHourYhj::getDeviceId, Collectors.reducing(0, TwinCalcHourYhj::getLength, Integer::sum)));
        for (Integer deviceId : calcMap.keySet()) {
            TwinCalcDayYhj calc = resultMap.get(deviceId);
            calc.setDayLength(calcDay.get(deviceId));
            yhjList.add(calc);
        }

        try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
            if (yhjList.size() > 0) {
                TwinCalcDayYhjMapper mapper = sqlSession.getMapper(TwinCalcDayYhjMapper.class);
                yhjList.forEach(mapper::insertTwinCalcDayYhj);
                sqlSession.commit();
            }
        }

    }
}
