package com.sifang.modules.supply.order.service;

import com.jfinal.kit.StrKit;
import com.sifang.modules.platform.utils.PlantformUtils;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.supply.order.dao.MaterialOutStockOrderDao;
import com.sifang.modules.supply.order.dao.MaterialOutStockOrderDetailDao;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialUsedOrder;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialUsedOrderDetail;
import com.sifang.modules.supply.order.request.OutStockDetailReq;
import com.sifang.modules.supply.order.request.OutStockReq;
import com.sifang.modules.supply.setting.constant.WarehouseConstants;
import com.sifang.modules.supply.setting.dao.CrmSupplyMaterialTypeDao;
import com.sifang.modules.supply.setting.dao.CrmSupplyWarehouseDao;
import com.sifang.modules.supply.setting.entity.CrmSupplyWarehouse;
import com.sifang.modules.supply.stock.constant.MaterialConstants;
import com.sifang.modules.supply.stock.dao.MaterialStockDao;
import com.sifang.modules.supply.stock.dao.SupplyMaterialDao;
import com.sifang.modules.supply.stock.entity.MaterialWarehouseStocks;
import com.sifang.modules.supply.stock.entity.SupplyMaterial;
import com.sifang.modules.supply.warehouse.constant.InventoryOrderConstants;
import com.sifang.modules.supply.warehouse.constant.MaterialKeepConstants;
import com.sifang.modules.supply.warehouse.dao.CrmSupplyMaterialKeepDao;
import com.sifang.modules.supply.warehouse.entity.CrmSupplyMaterialKeep;
import com.sifang.modules.supply.warehouse.service.CrmSupplyAllocationOrderService;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.dao.UserDao;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class OutStockOrderService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private MaterialOutStockOrderDao materialOutStockOrderDao;
    @Autowired
    private CrmSupplyWarehouseDao warehouseDao;
    @Autowired
    private SupplyMaterialDao materialDao;
    @Autowired
    private CrmSupplyAllocationOrderService allocationOrderService;
    @Autowired
    private MaterialOutStockOrderDao outStockOrderDao;
    @Autowired
    private MaterialOutStockOrderDetailDao outStockOrderDetailDao;
    @Autowired
    private CrmSupplyMaterialTypeDao materialTypeDao;
    @Autowired
    private MaterialStockDao materialStockDao;
    @Autowired
    private CrmSupplyMaterialKeepDao materialKeepDao;

    public LayuiPage getOutStockOrderPage(LayuiPage page, Map<String, String> map) {
        page.setData(materialOutStockOrderDao.listOutStockOrder(page, map));
        page.setCount(materialOutStockOrderDao.countOutStockOrder(map));
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrder(OutStockReq req) {
        User user = UserUtils.getUser();
        if (!StrKit.notNull(user.getId())) {// 小程序调用时 需要传递userId
            user = userDao.getById(req.getUserId());
            if (!StrKit.notNull(user)) {
                throw new BusinessException("userId不存在");
            }
        }
        checkBeforeSave(req);
        CrmSupplyMaterialUsedOrder order = new CrmSupplyMaterialUsedOrder();
        CrmSupplyWarehouse warehouse = warehouseDao.get(req.getWarehouseId());
        order.setNumber(PlantformUtils.findOrderNumber("CK"));
        order.setWarehouseId(warehouse.getId());
        order.setWarehouseName(warehouse.getName());
        order.setType(warehouse.getType());
        order.setAscriptionId(warehouse.getAscriptionId());
        order.setAscriptionName(warehouse.getAscriptionName());
        order.setRemarks(req.getRemarks());
        order.setCreateBy(user.getId());
        order.setCreator(CrmUtils.getUserXM(user));
        order.setCreateTime(new Date());
        order.setStatus("0");
        outStockOrderDao.save(order);

        List<OutStockDetailReq> details = req.getDetails();
        int sort = 1;
        for (OutStockDetailReq detail : details) {
            CrmSupplyMaterialUsedOrderDetail orderDetail = new CrmSupplyMaterialUsedOrderDetail();
            orderDetail.setMainId(order.getId());
            orderDetail.setSort(sort);

            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            orderDetail.setMaterialId(detail.getMaterialId());
            orderDetail.setMaterialCode(material.getCode());
            orderDetail.setMaterialType(materialTypeDao.get(material.getMaterialTypeId()).getName());
            orderDetail.setMaterialUnit(material.getUnitName());
            orderDetail.setMaterialRemarks(material.getRemarks());

            MaterialWarehouseStocks stocks = allocationOrderService.findWatehouseStock(material.getId(), req.getWarehouseId(), user);
            if (detail.getAmount().compareTo(stocks.getWarning()) > 0) {
                throw new BusinessException("第" + sort + "行物料库存不足");
            }
            orderDetail.setStock(stocks.getWarning());
            orderDetail.setAmount(detail.getAmount());
            orderDetail.setStatus("0");
            outStockOrderDetailDao.save(orderDetail);

            sort ++;
        }
        // 处理出库逻辑
        dealStockInfo(order, req.getDetails(), user);
    }

    private void dealStockInfo(CrmSupplyMaterialUsedOrder order, List<OutStockDetailReq> details, User user) {
        CrmSupplyWarehouse warehouse = warehouseDao.get(order.getWarehouseId());
        for (OutStockDetailReq detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            MaterialWarehouseStocks warehouseStocks = materialStockDao.findByWarehouse(detail.getMaterialId(), order.getWarehouseId());
            if (detail.getAmount().compareTo(warehouseStocks.getWarning()) > 0) {
                throw new BusinessException(String.format("物料编号【%s】库存不足", material.getCode()));
            }
            warehouseStocks.setWarning(warehouseStocks.getWarning().subtract(detail.getAmount()));
            warehouseStocks.setRealNum(warehouseStocks.getRealNum().subtract(detail.getAmount()));
            //warehouseStocks.setTotal(warehouseStocks.getTotal().subtract(detail.getAmount()));
            warehouseStocks.setNewestKeepTime(new Date());
            materialStockDao.save(warehouseStocks);
            // 生成出库记录
            CrmSupplyMaterialKeep keep = new CrmSupplyMaterialKeep();

            String belongingType = InventoryOrderConstants.DISTRIBUTOR.equals(warehouse.getType()) ?
                    InventoryOrderConstants.SUPPLIER :
                    (InventoryOrderConstants.SUPPLIER.equals(warehouse.getType()) ?
                            InventoryOrderConstants.DISTRIBUTOR : warehouse.getType());
            keep.setBelongingType(belongingType);
            keep.setMaterialId(material.getId());
            keep.setMaterialCode(material.getCode());
            keep.setMaterialUnit(material.getUnitName());
            keep.setMaterialRemarks(material.getRemarks());
            keep.setMaterialType(materialTypeDao.get(material.getMaterialTypeId()).getName());
            keep.setType(MaterialKeepConstants.OUT);
            keep.setAmount(detail.getAmount());
            keep.setCurBgNum(warehouseStocks.getWarning());
            keep.setWarehouseId(warehouse.getId());
            keep.setWarehouseName(warehouse.getName());

            keep.setAscriptionName(warehouse.getAscriptionName());
            keep.setAscriptionId(warehouse.getAscriptionId());
            keep.setCreateTime(new Date());
            keep.setCreateBy(user.getId());
            keep.setCreator(CrmUtils.getUserXM(user));
            keep.setSourceCode(order.getNumber());
            keep.setSourceId(order.getId());
            keep.setSource(MaterialKeepConstants.USED_OUT);
            keep.setRemarks(order.getRemarks());
            materialKeepDao.save(keep);
        }
    }

    public void checkBeforeSave(OutStockReq req) {
        CrmSupplyWarehouse warehouse = warehouseDao.get(req.getWarehouseId());
        if (!StrKit.notNull(warehouse)) {
            throw new BusinessException("出库仓库不存在");
        }
        if (!WarehouseConstants.NORMAL.equals(warehouse.getStatus())) {
            throw new BusinessException("出库仓库状态异常");
        }
        List<OutStockDetailReq> details = req.getDetails();
        if (details.isEmpty()) {
            throw new BusinessException("出库明细不能为空");
        }
        int index = 1;
        for (OutStockDetailReq detail : details) {
            SupplyMaterial material = materialDao.get(detail.getMaterialId());
            if (!StrKit.notNull(material)) {
                throw new BusinessException("第" + index + "行物料不存在");
            }
            if (!MaterialConstants.NORMAL.equals(material.getStatus())) {
                throw new BusinessException("第" + index + "行物料状态异常");
            }
            if (BigDecimal.ZERO.compareTo(detail.getAmount()) >= 0) {
                throw new BusinessException("第" + index + "使用数量须大于0");
            }

            index ++;
        }
    }
}
