package com.jjt.inventory.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jjt.common.utils.DateUtils;
import com.jjt.inventory.domain.TwinCalcHourBpOut;
import com.jjt.inventory.mapper.TwinCalcHourBpOutMapper;
import com.jjt.inventory.service.ITwinCalcHourBpOutService;
import com.jjt.inventory.vo.StockBpOutVO;
import com.jjt.utils.MssqlService;
import com.jjt.utils.Tools;
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.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 白坯投放量小时数据Service业务层处理
 *
 * @author wukai
 * @date 2025-06-11
 */
@Service
public class TwinCalcHourBpOutServiceImpl implements ITwinCalcHourBpOutService {
    @Resource
    private TwinCalcHourBpOutMapper twinCalcHourBpOutMapper;
    @Resource
    private MssqlService mssqlService;

    @Resource
    private SqlSessionFactory factory;

    /**
     * 查询白坯投放量小时数据
     *
     * @param id 白坯投放量小时数据主键
     * @return 白坯投放量小时数据
     */
    @Override
    public TwinCalcHourBpOut selectTwinCalcHourBpOutById(Long id) {
        return twinCalcHourBpOutMapper.selectTwinCalcHourBpOutById(id);
    }

    /**
     * 查询白坯投放量小时数据列表
     *
     * @param twinCalcHourBpOut 白坯投放量小时数据
     * @return 白坯投放量小时数据
     */
    @Override
    public List<TwinCalcHourBpOut> selectTwinCalcHourBpOutList(TwinCalcHourBpOut twinCalcHourBpOut) {
        return twinCalcHourBpOutMapper.selectTwinCalcHourBpOutList(twinCalcHourBpOut);
    }

    /**
     * 新增白坯投放量小时数据
     *
     * @param twinCalcHourBpOut 白坯投放量小时数据
     * @return 结果
     */
    @Override
    public int insertTwinCalcHourBpOut(TwinCalcHourBpOut twinCalcHourBpOut) {
        return twinCalcHourBpOutMapper.insertTwinCalcHourBpOut(twinCalcHourBpOut);
    }

    /**
     * 修改白坯投放量小时数据
     *
     * @param twinCalcHourBpOut 白坯投放量小时数据
     * @return 结果
     */
    @Override
    public int updateTwinCalcHourBpOut(TwinCalcHourBpOut twinCalcHourBpOut) {
        return twinCalcHourBpOutMapper.updateTwinCalcHourBpOut(twinCalcHourBpOut);
    }

    /**
     * 批量删除白坯投放量小时数据
     *
     * @param ids 需要删除的白坯投放量小时数据主键
     * @return 结果
     */
    @Override
    public int deleteTwinCalcHourBpOutByIds(Long[] ids) {
        return twinCalcHourBpOutMapper.deleteTwinCalcHourBpOutByIds(ids);
    }

    /**
     * 删除白坯投放量小时数据信息
     *
     * @param id 白坯投放量小时数据主键
     * @return 结果
     */
    @Override
    public int deleteTwinCalcHourBpOutById(Long id) {
        return twinCalcHourBpOutMapper.deleteTwinCalcHourBpOutById(id);
    }

    /**
     * 按小时白坯投放数据
     */
    @Override
    public void hour() {
        LocalDateTime ldt = Tools.currWholeTime();
        LocalDateTime start = ldt.minusHours(1);
        LocalDateTime end = ldt.minusSeconds(1);
        calc(start, end);
    }

    /**
     * 指定时间白坯投放数据
     *
     * @param start 开始
     * @param end   结束
     */
    @Override
    public void calc(LocalDateTime start, LocalDateTime end) {
        String sqlSuffix = " AND [时间] BETWEEN CONVERT(DATETIME, '" + start.toString().replace("T", " ") + "') AND CONVERT(DATETIME, '" + end.toString().replace("T", " ") + "')";
        String outSql = "SELECT [时间] TIME,[仓库编码] CODE,[仓库名称] NAME,[物料编码] SKU,[物料描述] SKU_DESCRC,[当日出库量] NUM,[单托_支数_米数] LENGTH,[单重_KG] WEIGHT,[产线_目标库位名称] TARGET FROM V_MES_FAYUN t" +
                " WHERE [仓库编码]='WH04' AND [产线_目标库位名称] LIKE '%上料点'" + sqlSuffix;
        List<Map<String, Object>> outList = mssqlService.executeQuery(outSql);
        Map<String, StockBpOutVO> stats = new HashMap<>(16);
        outList.forEach(map -> {
            String target = (String) map.get("TARGET");
            //“染整白坯7#上料点”，解析产线
            String line = target.replace("染整白坯", "").replace("#上料点", "");
            int length = map.get("LENGTH") != null ? new BigDecimal(map.get("LENGTH").toString()).intValue() : 0;
            int weight = map.get("WEIGHT") != null ? new BigDecimal(map.get("WEIGHT").toString()).intValue() : 0;

            StockBpOutVO vo = stats.computeIfAbsent(line, k -> new StockBpOutVO());
            vo.setLine(line);
            vo.addLength(length);
            vo.addWeight(weight);
        });

        List<StockBpOutVO> list = new ArrayList<>(stats.values());
        List<TwinCalcHourBpOut> bpOuts = new ArrayList<>();
        list.forEach(vo -> {
            TwinCalcHourBpOut out = new TwinCalcHourBpOut();
            out.setDataDate(DateUtils.toDate(start.toLocalDate()));
            out.setHour(start.getHour());
            out.setDeviceId(Integer.parseInt(vo.getLine()));
            out.setLength(vo.getLength());
            out.setWeight(vo.getWeight());
            bpOuts.add(out);
        });
        delete(start.toLocalDate(), start.getHour());
        try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
            if (bpOuts.size() > 0) {
                TwinCalcHourBpOutMapper mapper = sqlSession.getMapper(TwinCalcHourBpOutMapper.class);
                bpOuts.forEach(mapper::insertTwinCalcHourBpOut);
                sqlSession.commit();
            }
        }
    }


    /**
     * 删除白坯仓库小时数据信息
     *
     * @param date 日期
     * @param hour 小时
     */
    public void delete(LocalDate date, int hour) {
        QueryWrapper<TwinCalcHourBpOut> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("data_date", date);
        queryWrapper.eq("hour", hour);
        twinCalcHourBpOutMapper.delete(queryWrapper);
    }

}
