package com.ruoyi.web.stock.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.stock.domain.WarehouseIn;
import com.ruoyi.web.stock.domain.WarehouseInGoods;
import com.ruoyi.web.stock.domain.WarehouseInventory;
import com.ruoyi.web.stock.domain.vo.MaterialOptionVo;
import com.ruoyi.web.stock.mapper.WarehouseInboundMapper;
import com.ruoyi.web.stock.mapper.WarehouseInventoryMapper;
import com.ruoyi.web.stock.service.IWarehouseInboundService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 生产入库 Service 实现。
 */
@Service
public class WarehouseInboundServiceImpl implements IWarehouseInboundService {

    @Autowired
    private WarehouseInboundMapper warehouseInboundMapper;
    @Autowired
    private WarehouseInventoryMapper warehouseInventoryMapper;

    @Override
    public WarehouseIn selectById(Long id) {
        WarehouseIn entity = warehouseInboundMapper.selectWarehouseInById(id);
        if (entity != null) {
            entity.setGoodsList(warehouseInboundMapper.selectWarehouseInGoodsByInId(id));
        }
        return entity;
    }

    @Override
    public List<WarehouseIn> selectList(WarehouseIn query) {
        return warehouseInboundMapper.selectWarehouseInList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int submitInbound(WarehouseIn entity, String operator) {
        validateSubmit(entity);
        normalizeInbound(entity);
        entity.setSheetNo(generateSheetNo(entity.getOrgId(), entity.getSheetDate()));
        entity.setCreateBy(operator);
        entity.setUpdateBy(operator);
        entity.setDelFlag("0");
        warehouseInboundMapper.insertWarehouseIn(entity);

        List<WarehouseInGoods> goodsList = entity.getGoodsList();
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (WarehouseInGoods goods : goodsList) {
            normalizeGoods(goods);
            goods.setInId(entity.getId());
            goods.setSheetNo(entity.getSheetNo());
            goods.setOrgId(entity.getOrgId());
            goods.setCreateBy(operator);
            goods.setUpdateBy(operator);
            goods.setDelFlag("0");
            totalAmount = totalAmount.add(goods.getAmount());
            increaseInventory(entity.getOrgId(), operator, goods);
        }
        warehouseInboundMapper.insertWarehouseInGoodsBatch(goodsList);
        warehouseInboundMapper.updateWarehouseInTotalAmount(entity.getId(), totalAmount, operator);
        entity.setTotalAmount(totalAmount);
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(Long id, String operator) {
        warehouseInboundMapper.deleteWarehouseInGoodsByInId(id, operator);
        return warehouseInboundMapper.deleteWarehouseInById(id, operator);
    }

    @Override
    public List<MaterialOptionVo> listMaterialOptions(String orgId) {
        return warehouseInboundMapper.selectMaterialDetailOptions(orgId);
    }

    private void validateSubmit(WarehouseIn entity) {
        if (entity == null) {
            throw new ServiceException("提交失败，参数不能为空");
        }
        if (entity.getSheetDate() == null) {
            throw new ServiceException("提交失败，货单日期不能为空");
        }
        if (StringUtils.isEmpty(entity.getProductionType())) {
            throw new ServiceException("提交失败，生产类型不能为空");
        }
        if (StringUtils.isEmpty(entity.getOrgId())) {
            throw new ServiceException("提交失败，企业标识不能为空");
        }
        if (entity.getGoodsList() == null || entity.getGoodsList().isEmpty()) {
            throw new ServiceException("提交失败，至少需要一条物料明细");
        }
    }

    private void normalizeInbound(WarehouseIn entity) {
        if (entity.getGoodsList() == null) {
            entity.setGoodsList(Collections.emptyList());
        }
        if (entity.getTotalAmount() == null) {
            entity.setTotalAmount(BigDecimal.ZERO);
        }
    }

    private void normalizeGoods(WarehouseInGoods goods) {
        if (goods == null || StringUtils.isEmpty(goods.getGoodsNum())) {
            throw new ServiceException("提交失败，存在未选择物料的明细");
        }
        if (StringUtils.isEmpty(goods.getBatchNo())) {
            throw new ServiceException("提交失败，批次号不能为空");
        }
        if (StringUtils.isEmpty(goods.getWarehouseNo())) {
            throw new ServiceException("提交失败，仓库不能为空");
        }
        if (goods.getBaseQty() == null) {
            goods.setBaseQty(BigDecimal.ZERO);
        }
        if (goods.getAssistantQty() == null) {
            goods.setAssistantQty(BigDecimal.ZERO);
        }
        if (goods.getAmount() == null) {
            goods.setAmount(BigDecimal.ZERO);
        }
    }

    public String generateSheetNo(String orgId, Date sheetDate) {
        String dateText = new SimpleDateFormat("yyyyMMdd").format(sheetDate);
        Integer maxSeq = warehouseInboundMapper.selectTodayMaxSeq(orgId, dateText);
        int nextSeq = (maxSeq == null ? 0 : maxSeq) + 1;
        return dateText + String.format("%04d", nextSeq);
    }

    private void increaseInventory(String orgId, String operator, WarehouseInGoods goods) {
        WarehouseInventory old = warehouseInventoryMapper.selectByUniqueKey(orgId, goods.getWarehouseNo(), goods.getGoodsNum(), goods.getBatchNo());
        if (old == null) {
            WarehouseInventory add = new WarehouseInventory();
            add.setOrgId(orgId);
            add.setWarehouseNo(goods.getWarehouseNo());
            add.setWarehouseName(goods.getWarehouseName());
            add.setGoodsNum(goods.getGoodsNum());
            add.setGoodsName(goods.getGoodsName());
            add.setBatchNo(goods.getBatchNo());
            add.setStockQty(goods.getBaseQty());
            add.setAssistStockQty(goods.getAssistantQty());
            add.setCostAmount(goods.getAmount());
            add.setDelFlag("0");
            add.setCreateBy(operator);
            add.setUpdateBy(operator);
            warehouseInventoryMapper.insertWarehouseInventory(add);
            return;
        }
        warehouseInventoryMapper.increaseInventory(old.getId(), goods.getBaseQty(), goods.getAssistantQty(), goods.getAmount(), operator);
    }
}
