package com.zg.project.information.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

import com.zg.common.exception.ServiceException;
import com.zg.common.utils.StringUtils;
import com.zg.project.wisdom.domain.GysJh;
import com.zg.project.wisdom.domain.vo.PlanToMtdVO;
import com.zg.project.wisdom.mapper.GysJhMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import com.zg.project.information.mapper.MtdMapper;
import com.zg.project.information.domain.Mtd;
import com.zg.project.information.service.IMtdService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 物料字典Service业务层处理
 * 
 * @author zg
 * @date 2025-07-31
 */
@Service
public class MtdServiceImpl implements IMtdService 
{
    @Autowired
    private MtdMapper mtdMapper;

    // 注入若依内置线程池
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private GysJhMapper gysJhMapper;

    /**
     * 查询物料字典
     * 
     * @param Id 物料字典主键
     * @return 物料字典
     */
    @Override
    public Mtd selectMtdById(Long Id)
    {
        return mtdMapper.selectMtdById(Id);
    }

    /**
     * 查询物料字典列表
     * 
     * @param mtd 物料字典
     * @return 物料字典
     */
    @Override
    public List<Mtd> selectMtdList(Mtd mtd)
    {
        return mtdMapper.selectMtdList(mtd);
    }

    /**
     * 新增物料字典
     * 
     * @param mtd 物料字典
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertMtd(Mtd mtd)
    {
        if (mtd == null || StringUtils.isBlank(mtd.getMid())) {
            throw new ServiceException("物料号不能为空");
        }

        // 1️⃣ 先新增物料字典
        int rows = mtdMapper.insertMtd(mtd);

        // 2️⃣ 新增成功后，开始“反查供应计划”
        if (rows > 0 && StringUtils.isNotBlank(mtd.getUnt())) {

            String wlNo = mtd.getMid().trim();
            String dw   = mtd.getUnt().trim();

            // 3️⃣ 根据物料号查询供应计划（可能多条）
            List<GysJh> jhList = gysJhMapper.selectByWlNo(wlNo);

            if (jhList != null && !jhList.isEmpty()) {
                for (GysJh jh : jhList) {

                    // 4️⃣ 只处理「供应计划中单位为空」的记录
                    if (StringUtils.isBlank(jh.getDw())) {
                        gysJhMapper.updateDwById(jh.getId(), dw);
                    }
                }
            }
        }

        return rows;
    }

    /**
     * 修改物料字典
     * 
     * @param mtd 物料字典
     * @return 结果
     */
    @Override
    public int updateMtd(Mtd mtd)
    {
        return mtdMapper.updateMtd(mtd);
    }

    /**
     * 批量删除物料字典
     * 
     * @param Ids 需要删除的物料字典主键
     * @return 结果
     */
    @Override
    public int deleteMtdByIds(Long[] Ids)
    {
        return mtdMapper.deleteMtdByIds(Ids);
    }

    /**
     * 删除物料字典信息
     * 
     * @param Id 物料字典主键
     * @return 结果
     */
    @Override
    public int deleteMtdById(Long Id)
    {
        return mtdMapper.deleteMtdById(Id);
    }

    /**
     * 导入 Excel 数据（存在则更新，不存在则新增）
     */
    @Override
    public String importMtd(List<Mtd> mtdList, boolean updateSupport, String operName)
    {
        if (mtdList == null || mtdList.isEmpty()) {
            throw new ServiceException("导入数据不能为空！");
        }

        int nThreads = 3; // 启动3个线程
        int size = mtdList.size();
        int chunk = (size + nThreads - 1) / nThreads;

        AtomicInteger insertCount = new AtomicInteger(0);
        AtomicInteger updateCount = new AtomicInteger(0);
        AtomicInteger failCount   = new AtomicInteger(0);
        ConcurrentLinkedQueue<String> errorMsgs = new ConcurrentLinkedQueue<>();

        List<CompletableFuture<Void>> futures = new ArrayList<>();

        for (int t = 0; t < nThreads; t++) {
            int from = t * chunk;
            int to = Math.min(from + chunk, size);
            if (from >= to) break;

            final List<Mtd> part = mtdList.subList(from, to);
            final int startRow = 2 + from;

            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                for (int i = 0; i < part.size(); i++) {
                    Mtd row = part.get(i);
                    int rowNum = startRow + i;
                    try {
                        if (row.getMid() == null || row.getMid().trim().isEmpty()) {
                            failCount.incrementAndGet();
                            errorMsgs.add("第" + rowNum + "行：物料号为空；");
                            continue;
                        }

                        String mid = row.getMid().trim();
                        Mtd exist = mtdMapper.selectMtdByMid(mid);
                        if (exist == null) {
                            row.setCreateBy(operName);
                            mtdMapper.insertMtd(row);
                            insertCount.incrementAndGet();
                        } else if (updateSupport) {
                            exist.setDesMat(row.getDesMat());
                            exist.setGrp(row.getGrp());
                            exist.setUnt(row.getUnt());
                            exist.setUprc(row.getUprc());
                            exist.setBtpe(row.getBtpe());
                            exist.setMtpe(row.getMtpe());
                            exist.setStpe(row.getStpe());
                            exist.setUpdateBy(operName);
                            mtdMapper.updateMtd(exist);
                            updateCount.incrementAndGet();
                        } else {
                            failCount.incrementAndGet();
                            errorMsgs.add("第" + rowNum + "行：物料号(" + mid + ")已存在，跳过；");
                        }
                    } catch (Exception e) {
                        failCount.incrementAndGet();
                        errorMsgs.add("第" + rowNum + "行导入异常：" + e.getMessage() + "；");
                    }
                }
            }, threadPoolTaskExecutor);
            futures.add(future);
        }

        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

        String summary = String.format("导入完成：新增 %d 条，更新 %d 条，失败 %d 条。",
                insertCount.get(), updateCount.get(), failCount.get());
        if (failCount.get() > 0) {
            StringBuilder sb = new StringBuilder(summary).append(" 失败详情：");
            errorMsgs.forEach(sb::append);
            throw new ServiceException(sb.toString());
        }
        return summary;
    }

    @Override
    public int syncFromGysPlan(String operName) {
        // 查出“供应计划里有、物料字典里没有”的物料（去重）
        List<PlanToMtdVO> needAdd = gysJhMapper.selectMissingMtdItems();
        if (needAdd == null || needAdd.isEmpty()) return 0;

        int cnt = 0;
        for (PlanToMtdVO it : needAdd) {
            Mtd m = new Mtd();
            m.setMid(it.getWlNo());                      // 物料号
            m.setDesMat(it.getWlMs());                   // 物料描述
            m.setUnt(it.getDw());                        // 单位
            m.setUprc(it.getHtDj() == null ? null : it.getHtDj().toPlainString()); // 单价（字符串）
            m.setCreateBy(operName);
            cnt += mtdMapper.insertMtd(m);
        }
        return cnt;
    }
}
