package com.hys.app.service.erp.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.hys.app.converter.erp.ProductStockConverter;
import com.hys.app.converter.erp.WarehouseAreaConverter;
import com.hys.app.converter.erp.WarehouseOutItemConverter;
import com.hys.app.framework.context.user.AdminUserContext;
import com.hys.app.framework.database.BaseQueryParam;
import com.hys.app.framework.database.WebPage;
import com.hys.app.framework.database.mybatisplus.base.BaseServiceImpl;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.mapper.erp.WarehouseAreaMapper;
import com.hys.app.mapper.erp.WarehouseOutItemMapper;
import com.hys.app.model.erp.dos.*;
import com.hys.app.model.erp.dto.WarehouseAreaQueryParams;
import com.hys.app.model.erp.dto.WarehouseDTO;
import com.hys.app.model.erp.dto.WarehouseOutItemQueryParams;
import com.hys.app.model.erp.vo.*;
import com.hys.app.service.erp.*;
import lombok.AllArgsConstructor;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;

/**
 * 出库单商品明细业务层实现
 *
 * @author 张崧
 * @since 2023-12-07 17:06:32
 */
@Service
@AllArgsConstructor
public class WarehouseAreaManagerImpl extends BaseServiceImpl<WarehouseAreaMapper, WarehouseAreaDO> implements WarehouseAreaManager {

    private WarehouseAreaConverter converter;
    private WarehouseManager warehouseManager;
    private ProductStockManager productStockManager;
    private ProductStockConverter productConverter;
    private ProductManager productManager;
    private AreaStockManager areaStockManager;


    @Override
    public WebPage<WarehouseAreaVO> list(WarehouseAreaQueryParams queryParams) {
        WebPage<WarehouseAreaDO> webPage = baseMapper.selectPage(queryParams);
        WebPage<WarehouseAreaVO> webPage1 = converter.convert(webPage);
        for (WarehouseAreaVO item : webPage1.getData()) {
            WarehouseVO warehouseVO = warehouseManager.getDetail(item.getWarehouseId());
            long count = areaStockManager.count(new LambdaQueryWrapper<AreaStock>().eq(AreaStock::getWarehouseAreaId, item.getId()));
            item.setBindNum(count);
            item.setWarehouse(warehouseVO);
        }
        return webPage1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(WarehouseAreaDO warehouseAreaDO) {
        WarehouseAreaDO one = this.baseMapper.selectOne(new LambdaQueryWrapper<WarehouseAreaDO>()
                .eq(WarehouseAreaDO::getWarehouseId, warehouseAreaDO.getWarehouseId())
                .eq(WarehouseAreaDO::getCode, warehouseAreaDO.getCode()));
        if (ObjectUtil.isNotNull(one)) {
            throw new ServiceException("该仓库下库位编号已存在");
        }
        warehouseAreaDO.setCompanyId(AdminUserContext.getCompanyId());
        save(warehouseAreaDO);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(WarehouseAreaDO warehouseAreaDO) {
        if (warehouseAreaDO.getId() <= 0) {
            throw new ServiceException("库位信息更新失败,库位信息不存在");
        }
        updateById(warehouseAreaDO);
    }

    @Override
    public Page<ProductStockVO> goodNotAreaList(BaseQueryParam queryParam, Long warehouseId) {
        Page<ProductStockDO> page = productStockManager.page(new Page<>( queryParam.getPageNo(),queryParam.getPageSize()),
                new LambdaQueryWrapper<ProductStockDO>().eq(ProductStockDO::getWarehouseId, warehouseId)
                        .and(StrUtil.isNotBlank(queryParam.getKeyWord()), wa -> wa
                                .like(ProductStockDO::getGoodsName, queryParam.getKeyWord())
                                .or()
                                .like(ProductStockDO::getGoodsBarCode, queryParam.getKeyWord())
                                .or()
                                .like(ProductStockDO::getGoodsSnCode, queryParam.getKeyWord())));
        Page<ProductStockVO> convert = productConverter.convert(page);
        return convert;
    }

    @Override
    public List<WarehouseAreaDO> getAreaByWarehouse(Long warehouseId) {
        return list(new LambdaQueryWrapper<WarehouseAreaDO>().eq(WarehouseAreaDO::getWarehouseId, warehouseId));
    }

    @Override
    public void bindAreaStock(Long warehouseId, Long warehouseAreaId, List<Long> stockIdList) {
        WarehouseAreaDO areaDO = getById(warehouseAreaId);
        areaStockManager.remove(new LambdaQueryWrapper<AreaStock>()
                .eq(AreaStock::getWarehouseAreaId, warehouseAreaId)
                .eq(AreaStock::getWarehouseAreaId, warehouseAreaId)
                .in(AreaStock::getProductStockId, stockIdList));
        List<AreaStock> list = new ArrayList<>();
        for (Long aLong : stockIdList) {
            AreaStock stock = new AreaStock();
            stock.setProductStockId(aLong);
            stock.setWarehouseAreaName(areaDO.getCode());
            stock.setWarehouseId(warehouseId);
            stock.setCompanyId(AdminUserContext.getCompanyId());
            stock.setWarehouseAreaId(warehouseAreaId);
            list.add(stock);
        }
        areaStockManager.saveBatch(list);
    }


    @Override
    public WarehouseAreaVO getDetail(Long id) {
        WarehouseAreaVO vo = converter.convert(getById(id));
        if (!Objects.isNull(vo)) {
            WarehouseVO warehouseVO = warehouseManager.getDetail(vo.getWarehouseId());
            vo.setWarehouse(warehouseVO);
        }
        List<AreaStock> list = areaStockManager.list(new LambdaQueryWrapper<AreaStock>().eq(AreaStock::getWarehouseAreaId, id));
        for (AreaStock stock : list) {
            ProductStockDO byId = productStockManager.getById(stock.getProductStockId());
            stock.setProductVO(productManager.getById(byId.getProductId()));
            stock.setProductStockVO(byId);
        }
        vo.setAreaStockVO(list);
        return vo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        removeById(id);
    }


}

