package com.ruoyi.inventory.service.impl;

import java.io.File;
import java.util.*;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.common.core.domain.entity.Materials;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.inventory.domain.OutboundOrderItems;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.inventory.mapper.MaterialsMapper;
import com.ruoyi.inventory.service.IMaterialsService;
import org.apache.commons.lang3.SystemUtils;

/**
 * 物料Service业务层处理
 *
 * @author ruoyi
 * @date 2025-11-28
 */
@Service
public class MaterialsServiceImpl implements IMaterialsService
{
    @Autowired
    private MaterialsMapper materialsMapper;
    private static final Logger log = LoggerFactory.getLogger(MaterialsServiceImpl.class);
    /**
     * 查询物料
     *
     * @param id 物料主键
     * @return 物料
     */
    @Override
    public Materials selectMaterialsById(String id)
    {
        return materialsMapper.selectMaterialsById(id);
    }

    /**
     * 查询物料列表
     *
     * @param materials 物料
     * @return 物料
     */
    public List<Materials> selectMaterialsList(Materials materials)
    {
        return materialsMapper.selectMaterialsList(materials);
    }

    @Override
    public List<Materials> ListMaterialsInventory(Materials materials) {
        return materialsMapper.selectMaterialsInventoryList(materials);
    }

    /**
     * 新增物料
     *
     * @param materials 物料
     * @return 结果
     */
    @Override
    public int insertMaterials(Materials materials)
    {
        List<Materials> materialsList = materialsMapper.selectMaterialsBySapNo(materials.getSapNo());
        if (materialsList == null || materialsList.isEmpty()){
            materials.setId(UUID.randomUUID().toString());
            materials.setCreateTime(DateUtils.getNowDate());
            materials.setCreateUserCode(SystemUtils.getUserName());
            materials.setCreateBy(SystemUtils.getUserName());
            materials.setIsUsed(1L);
            return materialsMapper.insertMaterials(materials);
        }else{
            return updateMaterials(materials);
        }
    }

    /**
     * 修改物料(调用updateMaterialsIsUsed方法将原本的物料有效状态设置为0)
     *
     * @param materials 物料
     * @return 结果
     */
    @Override
    public int updateMaterials(Materials materials)
    {
        String[] ids = materials.getId().split(",");
        updateMaterialsIsUsed(ids);

        materials.setId(UUID.randomUUID().toString());

        materials.setUpdateUserCode(SystemUtils.getUserName());
        materials.setUpdateBy(SystemUtils.getUserName());
        materials.setUpdateTime(DateUtils.getNowDate());
        materials.setIsUsed(1L);
        return materialsMapper.insertMaterials(materials);
    }

    /**
     * 修改物料的使用状态(删除用)
     *
     * @param ids 需要删除的物料主键
     * @return 结果
     */
    @Override
    public int updateMaterialsIsUsed(String[] ids) {
        return materialsMapper.updateMaterialsIsUsedByIds(ids);
    }

    /**
     * 导入物料
     *
     * @param materialsList 物料列表
     * @return 结果
     */
    @Override
    public String importMaterials(List<Materials> materialsList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(materialsList) || materialsList.size() == 0)
        {
            throw new ServiceException("导入用户数据不能为空！");
        }
        int totalNum = 0;
        int successNum = 0;
        int failureNum = 0;
        int updateNum = 0;
        List<String> sapList = extractSapCodes(materialsList);

        List<Materials> sapExist = materialsMapper.sapIsExist(sapList);
        Map<String,Integer> sapMap = new HashMap<>();
        for (Materials materials : sapExist){
            sapMap.put(materials.getSapNo(),1);
        }
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        Date now = DateUtils.getNowDate();
        Long userId = SecurityUtils.getUserId();
        String operId = userId.toString();
        for (Materials materials : materialsList)
        {
            try
            {
                totalNum++;
                String sapNo = materials.getSapNo();
                String materialName = materials.getMaterialName();
                if (StringUtils.isBlank(sapNo) || StringUtils.isBlank(materialName)) {
                    failureNum++;
                    continue;
                }
                sapNo = materials.getSapNo().trim();
                materials.setSapNo(sapNo);

                materials.setId(UUID.randomUUID().toString());
                // 填充创建人、创建时间、修改人、修改时间
                materials.setCreateBy(operId);
                materials.setCreateTime(now);
                // 填充创建用户编码和更新用户编码
                materials.setCreateUserCode(operId);
                // 设置默认值
                if (materials.getIsActive() == null)
                {
                    materials.setIsActive(1L); // 默认激活
                }
                if (materials.getIsUsed() == null)
                {
                    materials.setIsUsed(1L); // 默认未删除
                }
                if (materials.getSortNo() == null)
                {
                    materials.setSortNo(0L); // 默认排序号
                }
                if (sapMap.get(materials.getSapNo()) == null){
                    materialsMapper.insertMaterials(materials);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、物料 " + materials.getMaterialName() + " 导入成功");
                }else{
                    updateMaterials(materials);
                    updateNum++;
                    successMsg.append("<br/>" + updateNum + "、物料 " + materials.getMaterialName() + " 已存在，覆盖完成");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、物料 " + materials.getMaterialName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确,SAPNo或物料名称可能不存在");
        }
        successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + totalNum + " 条，数据如下：");
        successMsg.append("<br/>" + failureMsg);
        return successMsg.toString();
    }

    /**
     * 从物料列表中提取SAP标识并去重
     * @param materialsList 物料列表（核心参数替换为这个）
     * @return 去重后的SAP标识列表
     */
    private List<String> extractSapCodes(List<Materials> materialsList) {
        // 1. 初始化Set用于自动去重
        Set<String> sapCodeSet = new HashSet<>();

        // 2. 判空：避免传入null列表导致空指针
        if (materialsList == null || materialsList.isEmpty()) {
            log.warn("物料列表为空，未提取到任何SAP标识");
            return new ArrayList<>();
        }

        // 3. 遍历物料列表，提取SAP标识
        for (Materials material : materialsList) {
            // 防御性判空：避免单个物料对象为null
            if (material == null) {
                continue;
            }

            // 4. 获取SAP标识（替换为你实际的getter方法，比如getSapId()）
            String sapCode = material.getSapNo();

            // 5. 过滤空值/空白字符串/无效值（和原逻辑一致）
            if (StringUtils.hasText(sapCode) && !"null".equalsIgnoreCase(sapCode.trim())) {
                // 统一trim去空格，避免" SAP001 "和"SAP001"被判定为不同值
                sapCodeSet.add(sapCode.trim());
            }
        }

        // 6. 打印日志（和原逻辑一致）
        log.info("物料列表解析完成，共提取到{}个不重复的SAP标识", sapCodeSet.size());

        // 7. Set转List返回
        return new ArrayList<>(sapCodeSet);
    }

    /**
     * @description: 获取物料 的 sap_no Name 做成字典
     * @author cs
     * @date 2025/12/4
     * @version 1.0
     */
    @Override
    public List<Map<String, Object>> getMapList(){
        return materialsMapper.getMapList();
    }

    /**
     * 删除物料信息（暂时无用）
     *
     * @param id 物料主键
     * @return 结果
     */
    @Override
    public int deleteMaterialsById(String id)
    {
        return materialsMapper.deleteMaterialsById(id);
    }

    @Override
    public List<Materials> selectMaterialsByCategory(String id) {
        return materialsMapper.selectMaterialsByCategory(id);
    }

    /**
     * 批量删除（暂时无用）
     *
     * @param ids 需要删除的物料主键
     * @return 结果
     */
    @Override
    public int deleteMaterialsByIds(String[] ids)
    {
        return  materialsMapper.deleteMaterialsByIds(ids);
    }
}
