package com.ruoyi.inventory.service.impl;

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

import com.ruoyi.common.annotation.SerialExecution;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.inventory.domain.*;
import com.ruoyi.inventory.domain.TO.StocktakeItemsTo;
import com.ruoyi.inventory.domain.vo.InventoryExceedWarnVO;
import com.ruoyi.inventory.domain.vo.InventorySummaryVO;
import com.ruoyi.inventory.domain.vo.InventoryVo;
import com.ruoyi.inventory.mapper.InboundOrdersMapper;
import com.ruoyi.inventory.mapper.OutboundOrderItemsMapper;
import com.ruoyi.inventory.mapper.OutboundOrderLogMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.SystemUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.inventory.mapper.InventoryMapper;
import com.ruoyi.inventory.service.IInventoryService;

/**
 * 库存Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-12-03
 */
@Service
public class InventoryServiceImpl implements IInventoryService
{
    @Autowired
    private InventoryMapper inventoryMapper;
    @Autowired
    private OutboundOrderLogMapper outboundOrderLogMapper;;
    @Autowired
    private OutboundOrderItemsMapper outboundOrderItemsMapper;
    @Autowired
    private OutboundOrdersServiceImpl outboundOrderMapper;
    @Autowired
    private InventoryTransactionsServiceImpl insertInventoryTransactions;
    @Autowired
    private InboundOrdersMapper inboundOrdersMapper;




    /**
     * 查询库存
     * 
     * @param id 库存主键
     * @return 库存
     */
    @Override
    public Inventory selectInventoryById(String id)
    {
        return inventoryMapper.selectInventoryById(id);
    }


    /**
     * 查询库存列表
     * 
     * @param inventory 库存
     * @return 库存
     */
    @Override
    public List<Inventory> selectInventoryList(Inventory inventory)
    {

        return inventoryMapper.selectInventoryList(inventory);
    }

    @Override
    public Inventory selectInventory(Inventory inventory)
    {
        return inventoryMapper.selectInventory(inventory);
    }

    /**
     * 新增库存
     * 
     * @param inventory 库存
     * @return 结果
     */
    @Override
    public int insertInventory(Inventory inventory)
    {
        inventory.setCreateTime(DateUtils.getNowDate());
        inventory.setCreateBy(SystemUtils.getUserName());
        inventory.setCreateUserCode(SystemUtils.getUserName());
        return inventoryMapper.insertInventory(inventory);
    }

    /**
     * 批量新增库存
     *
     * @param inventoryList 库存
     * @return 结果
     */
    @Override
    public int insertInventoryList(List<Inventory> inventoryList) {
        int count = 0;
        for (Inventory inventory : inventoryList) {
            inventory.setLastInboundTime(DateUtils.getNowDate());
            inventory.setCreateTime(DateUtils.getNowDate());
            inventory.setId(UUID.randomUUID().toString());
            inventory.setCreateBy(SystemUtils.getUserName());
            inventory.setCreateUserCode(SystemUtils.getUserName());
            inventory.setIsUsed(1L);
            createInventoryInboundLog(inventory,inventory.getQuantity(),inventory.getCreateUserCode(),inventory.getCreateTime());
            count = inventoryMapper.insertInventory(inventory);
        }
        return count;
    }

    /**
     * 修改库存
     * 
     * @param inventory 库存
     * @return 结果
     */
    @Override
    public int updateInventory(Inventory inventory)
    {

        List<Inventory> inventoryList = Collections.singletonList(inventory);
        inventory.setUpdateTime(DateUtils.getNowDate());
        inventory.setUpdateBy(SystemUtils.getUserName());
        return inventoryMapper.updateInventory(inventory);
    }

    @SerialExecution( group = "inventoryRefresh", fair = true)
    @Override
    public int RefreshInventory(List<String> inventoryIds)
    {
        for (String inventoryId : inventoryIds) {
            // 1. 空值前置校验：跳过空的循环项
            if (inventoryId == null) {
                continue;
            }

            // 6. 查询锁定数量（优化：只查一次）
            Long lockedQuantity = outboundOrderLogMapper.selectLockedQuantityByInventory(inventoryId);
            Inventory inventory = new Inventory();
            inventory.setLockedQuantity(lockedQuantity);
            inventory.setId(inventoryId);
            inventoryMapper.updateInventory(inventory);
        }
        return 1;
    }

    @SerialExecution(group = "inventoryRefresh", fair = true)
    @Override
    public int ship(List<OutboundOrderItems> outboundOrderItems)
    {
            if (!outboundOrderItems.isEmpty()) {
                List<String> inventoryIds = outboundOrderItems.stream().map(OutboundOrderItems::getInventoryId).collect(Collectors.toList());
                for (OutboundOrderItems outboundOrderItem : outboundOrderItems) {

                    OutboundOrderLog outboundOrderLog = outboundOrderLogMapper.selectOutboundOrderLogById(outboundOrderItem.getId());
                    Inventory inventory =inventoryMapper.selectInventoryById(outboundOrderLog.getInventoryId());
                    String quantity = String.valueOf(inventory.getQuantity());
                    inventory.setQuantity(inventory.getQuantity()-outboundOrderItem.getActualQuantity());
                    if (inventory.getQuantity()==0){
                        inventory.setInventoryStatus(0l);
                    }
                    updateInventory(inventory);

                    createInventoryOutboundLog(inventory,outboundOrderItem,Long.valueOf(quantity),SystemUtils.getUserName(),new Date());
                }
                RefreshInventory(inventoryIds);
            }
            return 1;
    }

    public void createInventoryOutboundLog(Inventory inventory, OutboundOrderItems outboundOrderItem,
                                           Long deductQty, String updateUser, Date updateTime) {
            InventoryTransactions transactions = new InventoryTransactions();
            transactions.setId(IdUtils.simpleUUID()); // 确保IdUtils工具类存在，若无则替换为UUID.randomUUID().toString()
            transactions.setTransactionType(2L); // 事务类型-出库
            transactions.setBatchCode(outboundOrderItem.getBatchCode());
            transactions.setUnitPrice(outboundOrderItem.getUnitPrice());
            transactions.setInventoryId(inventory.getId()); // 库存表Id
            transactions.setReferenceId(outboundOrderItem.getOutboundOrderId()); // 关联出库单主表ID
            transactions.setReferenceItemId(outboundOrderItem.getId()); // 关联出库单明细ID
            transactions.setMaterialId(outboundOrderItem.getMaterialId());
            transactions.setWarehouseId(outboundOrderItem.getWarehouseId());
            transactions.setLocationId(outboundOrderItem.getLocationId());

            // 补充货主ID（从出库单主表查询）
            OutboundOrders outboundOrders = outboundOrderMapper.selectOutboundOrdersById(outboundOrderItem.getOutboundOrderId());
            if (outboundOrders != null) {
                transactions.setOwnerId(outboundOrders.getOwnerId());
            }

            // 变更前后数量
            Long beforeQty = Optional.ofNullable(inventory.getQuantity()).orElse(0L) + deductQty; // 扣减前数量 = 扣减后 + 扣减量
            transactions.setQuantityBefore(beforeQty);
            transactions.setQuantityAfter(inventory.getQuantity()); // 扣减后数量
            transactions.setQuantityChange(deductQty); // 变更量（出库为正数）
            transactions.setTransactionTime(updateTime);
            transactions.setOperatedBy(updateUser);

            // 插入日志
            insertInventoryTransactions.insertInventoryTransactions(transactions);
    }



    //入库单确认入库日志
    private void createInventoryInboundLog(Inventory inventory,
                                            Long addQty, String createUser, Date createTime) {
        InventoryTransactions transactions = new InventoryTransactions();
        transactions.setId(IdUtils.simpleUUID()); // 确保IdUtils工具类存在，若无则替换为UUID.randomUUID().toString()
        transactions.setTransactionType(1L); // 事务类型-入库
        transactions.setBatchCode(inventory.getBatchId());
        transactions.setUnitPrice(inventory.getUnitPrice());
        transactions.setInventoryId(inventory.getId()); // 库存表Id
        transactions.setReferenceId(inventory.getInboundOrderId()); // 关联出库单主表ID
        transactions.setReferenceItemId(inventory.getId()); // 关联出库单明细ID
        transactions.setMaterialId(inventory.getMaterialId());
        transactions.setWarehouseId(inventory.getWarehousesId());
        transactions.setLocationId(inventory.getLocationId());
        transactions.setOwnerId(inventory.getOwnerId());
        // 新建实体，查看该物料在库存中数量，避免其他条件干扰
        Inventory inventoryBefore = new Inventory();
        inventoryBefore.setMaterialId(inventory.getMaterialId());
        List<Inventory> inventoryList = inventoryMapper.selectInventoryList(inventoryBefore);

        if (inventoryList == null) {
            inventoryBefore = new Inventory();
            inventoryBefore.setQuantity(0L);
        }else{
            Long quantity = 0L;
            for (Inventory inventoryItem : inventoryList) {
                quantity += inventoryItem.getQuantity();
            }
            inventoryBefore.setQuantity(quantity);
        }
        transactions.setQuantityBefore(inventoryBefore.getQuantity());
        transactions.setQuantityAfter(inventory.getQuantity() + addQty);
        transactions.setQuantityChange(addQty);
        transactions.setTransactionTime(createTime);
        transactions.setOperatedBy(createUser);

        // 插入日志
        insertInventoryTransactions.insertInventoryTransactions(transactions);
    }


    @SerialExecution(group = "inventoryRefresh", fair = true)
    @Override
    public boolean inventoryLockValidation(List<OutboundOrderItems> outboundOrderItems)
    {

        if (!outboundOrderItems.isEmpty()) {
            List<String> inventoryIds = outboundOrderItems.stream().map(OutboundOrderItems::getInventoryId).collect(Collectors.toList());
            RefreshInventory(inventoryIds);
            for (OutboundOrderItems outboundOrderItem : outboundOrderItems) {
                Inventory inventory = inventoryMapper.selectInventoryById(outboundOrderItem.getInventoryId());
                if (inventory.getLockedQuantity()+outboundOrderItem.getActualQuantity()>inventory.getQuantity()){
                    return false;
                }
            }
            return true;
        }
        return true;
    }
    /**
     * 批量删除库存
     * 
     * @param ids 需要删除的库存主键
     * @return 结果
     */
    @Override
    public int deleteInventoryByIds(String[] ids)
    {
        return inventoryMapper.deleteInventoryByIds(ids);
    }

    /**
     * 删除库存信息
     * 
     * @param id 库存主键
     * @return 结果
     */
    @Override
    public int deleteInventoryById(String id)
    {
        return inventoryMapper.deleteInventoryById(id);
    }

    @SerialExecution(group = "inventoryRefresh", fair = true)
    @Override
    public List<Inventory> listByMatreialId(OutboundOrderItems inventory) {

        String materialId = inventory.getMaterialId();
        List<String> inventoryIds = CollectionUtils.isEmpty(inventoryMapper.listByMaterialId(materialId))
                ? Collections.emptyList()  // 空时返回空列表，避免后续NPE
                : inventoryMapper.listByMaterialId(materialId).stream()
                .map(inventory2 -> inventory2.getId())  // 提取ID（核心修正）
                .collect(Collectors.toList());
        RefreshInventory(inventoryIds);

        return MyQuantity(inventory);
    }
    public List<Inventory> MyQuantity(OutboundOrderItems inventory){
        String materialId = inventory.getMaterialId();
        List<Inventory> inventoryList = inventoryMapper.listByMaterialId(materialId);
        OutboundOrderItems outboundOrderItem = new OutboundOrderItems();

        outboundOrderItem.setOutboundOrderId(inventory.getOutboundOrderId());
        List<OutboundOrderItems> outboundOrderItems = outboundOrderItemsMapper.selectOutboundOrderItemsList(outboundOrderItem);


        inventoryList.forEach(inventory2 -> {
            long deductQuantity = 0;
            if (inventory.getOutboundOrderId()!=null){
                 deductQuantity = outboundOrderItems.stream()
                    .filter(item -> item.getInventoryId().equals(inventory2.getId()))
                    .mapToLong(OutboundOrderItems::getActualQuantity)
                    .sum();
            }
            inventory2.setLockedQuantity(inventory2.getLockedQuantity() - deductQuantity);
        });

        // 过滤掉满足条件的元素，返回新集合
        return inventoryList.stream()
                .filter(inventory2 -> inventory2.getQuantity() > inventory2.getLockedQuantity())
                .collect(Collectors.toList());

    }
    /**
     * @description: 获取库存盘点详细信息
     * @author cs
     * @date 2025/12/3
     * @version 1.0
     */
    public List<StocktakeItemsTo> selectstocktakeItemsList(){
        return inventoryMapper.selectstocktakeItemsList();
    }

    /**
     * 按物料汇总统计库存
     * 
     * @param inventory 库存查询条件
     * @return 库存汇总统计集合
     */
    @Override
    public List<InventorySummaryVO> selectInventorySummaryList(Inventory inventory)
    {
        return inventoryMapper.selectInventorySummaryList(inventory);
    }

    /**
     * 查询库存明细列表（根据物料标识及检索条件）
     * 
     * @param inventory 库存查询条件
     * @return 库存明细集合
     */
    @Override
    public List<Inventory> selectInventoryDetailList(Inventory inventory)
    {
        return inventoryMapper.selectInventoryDetailList(inventory);
    }

    @Override
    public List<InventoryVo> selectInventoryVoList(Inventory inventory)
    {
        return inventoryMapper.selectInventoryVoList(inventory);
    }

    @Override
    public List<InventoryExceedWarnVO> selectInventoryExceedWarnList() {
        return inventoryMapper.selectInventoryExceedWarnList();
    }

    @Override
    public List<Map<String, String>> inventoryTopTenByAmount() {
        return inventoryMapper.selectInventoryTopTenByAmount();
    }

    @Override
    public List<Map<String, String>> inventoryTopTenByQuantity() {
        return inventoryMapper.selectInventoryTopTenByQuantity();
    }
}
