package com.ruoyi.inventory.service.impl;

import java.util.*;
import java.util.stream.Collectors;

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.StorageLocations;
import com.ruoyi.inventory.service.IWarehousesService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.inventory.mapper.WarehousesMapper;
import com.ruoyi.inventory.domain.Warehouses;

/**
 * 仓库Service业务层处理
 *
 * @author ruoyi
 * @date 2025-12-01
 */
@Service
public class WarehousesServiceImpl implements IWarehousesService
{
    @Autowired
    private WarehousesMapper warehousesMapper;
    @Autowired
    private StorageLocationsServiceImpl storageLocationsService;

    /**
     * 查询仓库
     *
     * @param id 仓库主键
     * @return 仓库
     */
    @Override
    public Warehouses selectWarehousesById(String id)
    {
        return warehousesMapper.selectWarehousesById(id);
    }

    /**
     * 查询仓库列表
     *
     * @param warehouses 仓库
     * @return 仓库
     */
    @Override
    public List<Warehouses> selectWarehousesList(Warehouses warehouses)
    {
        return warehousesMapper.selectWarehousesList(warehouses);
    }

    /**
     * 新增仓库
     *
     * @param warehouses 仓库
     * @return 结果
     */
    @Override
    public int insertWarehouses(Warehouses warehouses)
    {
        warehouses.setCreateTime(DateUtils.getNowDate());
        warehouses.setCreateUserCode(String.valueOf(SecurityUtils.getUserId()));
        warehouses.setId(UUID.randomUUID().toString());
        return warehousesMapper.insertWarehouses(warehouses);
    }

    /**
     * 修改仓库
     *
     * @param warehouses 仓库
     * @return 结果
     */
    @Override
    public int updateWarehouses(Warehouses warehouses)
    {
        warehouses.setUpdateUserCode(String.valueOf(SecurityUtils.getUserId()));
        warehouses.setUpdateTime(DateUtils.getNowDate());
        Warehouses warehouses1 = warehousesMapper.selectWarehousesById(warehouses.getId());
        if (warehouses1.getIsEnabled()!=warehouses.getIsEnabled()){
            updateWarehouseStatus(warehouses);
        }
        return warehousesMapper.updateWarehouses(warehouses);
    }
    @Override
    public int updateWarehouseStatus(Warehouses warehouses)
    {
        storageLocationsService.updateLocationsCategoryStatus(warehouses.getWarehousesCode());
        return warehousesMapper.updateWarehouseStatus(warehouses.getId());
    }

    /**
     * 批量删除仓库
     *
     * @param ids 需要删除的仓库主键
     * @return 结果
     */
    @Override
    public int deleteWarehousesByIds(String[] ids)
    {
        List<String> WarehousesCodes = new ArrayList<>();
        for (String id : ids){
            Warehouses warehouses = selectWarehousesById(id);
            String warehousesCode = warehouses.getWarehousesCode();
            WarehousesCodes.add(warehousesCode);
        }
        List<StorageLocations> storageLocations = new ArrayList<>();
        if (WarehousesCodes!=null && !WarehousesCodes.isEmpty()){
            storageLocations= storageLocationsService.selectStorageLocationsByWarehousesCodes(WarehousesCodes);
        }
          for (StorageLocations storageLocation : storageLocations) {
            storageLocationsService.deleteStorageLocationsById(storageLocation.getId());
        }
        return warehousesMapper.deleteWarehousesByIds(ids);
    }

    /**
     * 删除仓库信息
     *
     * @param id 仓库主键
     * @return 结果
     */
    @Override
    public int deleteWarehousesById(String id)
    {
        List<StorageLocations> storageLocations = storageLocationsService.selectStorageLocationsByWarehousesCode(id);
        for (StorageLocations storageLocation : storageLocations) {
            storageLocationsService.deleteStorageLocationsById(storageLocation.getId());
        }
        return warehousesMapper.deleteWarehousesById(id);
    }

    /**
     * @description: 获取仓库 的 warehouses_code 仓库编码 warehouses_name 做成字典
     * @author cs
     * @date 2025/12/4
     * @version 1.0
     */
    @Override
    public List<Map<String, Object>> getMapList(){
        return warehousesMapper.getMapList();
    }

    @Override
    public String importWarehouses(List<Warehouses> warehousesList, Boolean isUpdateSupport, String operName) {
        // 空数据校验
        if (CollectionUtils.isEmpty(warehousesList)) {
            throw new ServiceException("导入仓库数据不能为空！");
        }

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        Date now = DateUtils.getNowDate();
        // 获取当前登录用户ID
        Long userId = SecurityUtils.getUserId();
        String operId = userId.toString();

        // 批量插入的有效数据集合
        List<Warehouses> batchInsertList = new ArrayList<>();

        // ========== 核心优化：提前加载所有已存在的仓库编码映射 ==========
        Map<String, String> warehouseCodeToIdMap = warehousesCodeToIdMap();

        for (Warehouses warehouse : warehousesList) {
            // ========== 关键修复：先校验warehouse对象是否为null ==========
            if (warehouse == null) {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、导入失败：数据行不能为空（存在空对象）");
                continue; // 跳过空对象，继续处理下一条
            }

            try {
                // 核心校验：仓库编码不能为空
                String warehouseCode = warehouse.getWarehousesCode();
                if (warehouseCode == null || warehouseCode.trim().isEmpty()) {
                    // 修复原逻辑错误：当编码为空时，提示中用"未知编码"替代空值，避免展示【null】或空字符串
                    throw new ServiceException("【未知编码】仓库编码不能为空");
                }
                // 去除首尾空格，避免因空格导致的重复判断错误
                String cleanWarehouseCode = warehouseCode.trim();

                // 核心优化：从Map中校验仓库编码是否已存在（替代数据库查询）
                if (warehouseCodeToIdMap.containsKey(cleanWarehouseCode)) {
                    throw new ServiceException("仓库【" + cleanWarehouseCode + "】已存在");
                }

                // 生成UUID主键（根据实际主键策略调整，若数据库自增可删除）
                warehouse.setId(UUID.randomUUID().toString());

                // 填充公共字段
                warehouse.setCreateBy(operId);
                warehouse.setCreateTime(now);
                warehouse.setCreateUserCode(operId);
                if (warehouse.getIsUsed() == null) {
                    warehouse.setIsUsed(1L); // 默认未删除
                }
                if (warehouse.getSortNo() == null) {
                    warehouse.setSortNo(0L); // 默认排序号
                }

                // 加入批量集合
                batchInsertList.add(warehouse);
                successNum++;
                String warehouseName = warehouse.getWarehousesName() != null ? warehouse.getWarehousesName() : cleanWarehouseCode;
                successMsg.append("<br/>" + successNum + "、仓库 " + warehouseName + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String warehouseCode = warehouse.getWarehousesCode() != null ? warehouse.getWarehousesCode() : "未知编码";
                String msg = "<br/>" + failureNum + "、仓库编码 " + warehouseCode + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                // 异常数据跳过，继续处理下一条
                continue;
            }
        }

        // 批量插入有效数据（如果有）
        if (!CollectionUtils.isEmpty(batchInsertList)) {
            try {
                warehousesMapper.batchInsertWarehouses(batchInsertList);
            } catch (Exception e) {
                // 批量插入失败时，统计失败数量（不抛异常，仅记录）
                int batchFailNum = batchInsertList.size();
                failureNum += batchFailNum;
                successNum -= batchFailNum;
                failureMsg.insert(0, String.format("<br/>批量插入失败：%s，失败条数追加 %d 条",
                        e.getMessage(), batchFailNum));
            }
        }

        // 结果反馈处理
        StringBuilder resultMsg = new StringBuilder();
        if (successNum > 0) {
            resultMsg.append("数据导入完成！成功导入 " + successNum + " 条，成功列表如下：");
            resultMsg.append(successMsg);
        }
        if (failureNum > 0) {
            resultMsg.append("<br/><br/>失败导入 " + failureNum + " 条，失败原因如下：");
            resultMsg.append(failureMsg);
        }
        // 全部失败的友好提示
        if (successNum == 0 && failureNum > 0) {
            resultMsg.insert(0, "很抱歉，所有数据均导入失败！");
        }

        return resultMsg.toString();
    }

    private Map<String, String> warehousesCodeToIdMap() {
        Warehouses query = new Warehouses();
        query.setIsUsed(1L); // 仅查询未删除的仓库数据
        List<Warehouses> warehouseList = warehousesMapper.selectWarehousesList(query);

        if (org.springframework.util.CollectionUtils.isEmpty(warehouseList)) {
            return Collections.emptyMap();
        }
        return warehouseList.stream()
                .filter(w -> StringUtils.isNotBlank(w.getWarehousesCode()))
                // 核心优化：对编码去空格后作为Key，避免空格导致的匹配错误
                .collect(Collectors.toMap(
                        w -> w.getWarehousesCode().trim(),
                        Warehouses::getId,
                        (k1, k2) -> k1 // 存在重复编码时保留第一条（避免Map键冲突）
                ));
    }
}
