package net.lab1024.sa.admin.module.business.wms.base.stock.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.vo.ItemVO;
import net.lab1024.sa.admin.module.business.wms.base.item.domain.vo.ItemsExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.wms.base.location.manager.LocationManager;
import net.lab1024.sa.admin.module.business.wms.base.location.service.LocationQueryService;
import net.lab1024.sa.admin.module.business.wms.base.stock.dao.StockDao;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.entity.StockEntity;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockQueryForm;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.form.StockSelect;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StockVO;
import net.lab1024.sa.admin.module.business.wms.base.stock.domain.vo.StocksExcelVO;
import net.lab1024.sa.admin.module.business.wms.base.stock.manager.StockManager;
import net.lab1024.sa.admin.module.business.wms.base.stock.service.StockQueryService;
import net.lab1024.sa.admin.module.business.wms.excel.ExportTaskService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.util.SmartExcelUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.dict.constant.DictConst;
import net.lab1024.sa.base.module.support.dict.service.DictService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StockQueryServiceImpl implements StockQueryService {
    @Resource
    private StockDao stockDao;

    @Resource
    private LocationManager locationManager;

    @Resource
    private StockManager stockManager;

    @Resource
    private DictService dictService;

    @Resource
    private LocationQueryService locationQueryService;

    @Resource
    private ExportTaskService exportTaskService;

    /**
     * 分页查询
     *
     * @param queryForm 查询参数
     * @return PageResult<StockVO>
     */
    public PageResult<StockVO> queryPage(StockQueryForm queryForm) {
        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
        List<StockVO> list = stockDao.queryPage(page, queryForm);

        // 查询库位编码
        List<Long> locationIdList = list.stream().map(StockVO::getLocationId).toList();
        Map<Long, LocationEntity> locationMap = locationQueryService.queryByLocationIdsToMap(locationIdList);
        list.forEach(StockVO -> {
            LocationEntity location = locationMap.get(StockVO.getLocationId());
            if (location != null) {
                StockVO.setLocationCode(location.getLocationCode());
            }
        });
        return SmartPageUtil.convert2PageResult(page, list);
    }

    /**
     * 容器下拉查询
     *
     * @param stockSelect 入参
     * @return List<StockEntity>
     */
    public List<StockEntity> queryStock(StockSelect stockSelect) {
        LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
        //是否启用
        if (stockSelect.getDisabledFlag() != null) {
            queryWrapper.eq(StockEntity::getDisabledFlag, stockSelect.getDisabledFlag());
        }
        //状态
        if (StringUtils.isNotBlank(stockSelect.getStatus())) {
            queryWrapper.eq(StockEntity::getStatus, stockSelect.getStatus());
        }
        return stockManager.list(queryWrapper);
    }

    /**
     * 根据容器id集合查询容器信息
     *
     * @param stockIdList 容器id集合
     * @return Map<Long, StockEntity>
     */
    public Map<Long, StockEntity> queryByStockIdsToMap(List<Long> stockIdList) {
        if (CollectionUtils.isEmpty(stockIdList)) {
            return Collections.emptyMap();
        }
        stockIdList = stockIdList.stream().filter(Objects::nonNull).distinct().toList();
        Map<Long, StockEntity> stockMap = Maps.newHashMap();
        for (Long stockId : stockIdList) {
            StockEntity stock = stockManager.queryStock(stockId);
            if (stock != null) {
                stockMap.put(stockId, stock);
            }
        }
        return stockMap;
    }

    /**
     * 根据容器编码查询容器信息
     *
     * @param stockCode 容器编码
     * @return StockEntity
     */
    public StockEntity queryByStockCode(String stockCode) {
        if (StringUtils.isBlank(stockCode)) {
            return null;
        }
        LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StockEntity::getStockCode, stockCode);
        return stockManager.getOne(queryWrapper);
    }

    /**
     * 根据容器编码集合查询容器信息
     *
     * @param stockCodes 容器料编码集合
     * @return List<StockEntity>
     */
    public List<StockEntity> queryByStockCodes(List<String> stockCodes) {
        if (CollectionUtils.isEmpty(stockCodes)) {
            return Collections.emptyList();
        }
        stockCodes = stockCodes.stream().filter(Objects::nonNull).distinct().toList();
        LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(StockEntity::getStockCode, stockCodes);
        return stockManager.list(queryWrapper);
    }

    /**
     * 根据容器编码集合查询容器信息
     *
     * @param stockCodes 容器编码集合
     * @return Map<String, StockEntity>
     */
    public Map<String, StockEntity> queryByStockCodesToMap(List<String> stockCodes) {
        if (CollectionUtils.isEmpty(stockCodes)) {
            return Collections.emptyMap();
        }
        //查询容器
        List<StockEntity> stockList = queryByStockCodes(stockCodes);
        //封装map
        Map<String, StockEntity> stockMap = Maps.newHashMap();
        for (StockEntity stock : stockList) {
            stockMap.put(stock.getStockCode(), stock);
        }
        return stockMap;

    }

    /**
     * 根据库位id查询容器信息
     *
     * @param locationId 库位
     * @return StockEntity
     */
    public StockEntity queryStockByLocationId(Long locationId) {
        if (locationId == null) {
            return null;
        }
        LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StockEntity::getLocationId, locationId);
        return stockManager.getOne(queryWrapper);
    }

    /**
     * 容器导出
     *
     * @return List<StocksExcelVO>
     */
    public List<StocksExcelVO> queryStocksExcelVO() {
        List<StockEntity> stocksList = stockManager.list();
        return stocksList.stream()
                .map(stock ->
                        StocksExcelVO.builder()
                                .stockCode(stock.getStockCode())
                                .stockType(dictService.getDictDataLabel(DictConst.STOCK_TYPE.getValue(), stock.getStockType()))
                                .locationCode(locationManager.queryLocation(stock.getLocationId()) == null ? "" : locationManager.queryLocation(stock.getLocationId()).getLocationCode())
                                .disabledFlag(stock.getDisabledFlag() ? "启用" : "禁用")
                                .build()
                )
                .collect(Collectors.toList());
    }

    @Override
    public long stockCount(StockQueryForm queryForm) {
        LambdaQueryWrapper<StockEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (queryForm.getStockId() != null) {
            queryWrapper.eq(StockEntity::getStockId, queryForm.getStockId());
        }
        if (queryForm.getLocationId() != null) {
            queryWrapper.eq(StockEntity::getLocationId, queryForm.getLocationId());
        }
        if (StringUtils.isNotBlank(queryForm.getStatus())) {
            queryWrapper.eq(StockEntity::getStatus, queryForm.getStatus());
        }

        if (queryForm.getDisabledFlag() != null) {
            queryWrapper.eq(StockEntity::getDisabledFlag, queryForm.getDisabledFlag());
        }
        return stockManager.count(queryWrapper);
    }

    @Override
    public void exportStock(String taskId, StockQueryForm queryForm, HttpServletResponse response) {
        try {
            SmartExcelUtil.batchExportExcel(
                    response,
                    "容器信息.xlsx",
                    "容器信息",
                    StocksExcelVO.class,
                    taskId,
                    stockCount(queryForm),
                    (lastId, pageSize) -> stockDao.listByCursor(lastId, pageSize, queryForm),
                    stock -> StocksExcelVO.builder()
                            .stockCode(stock.getStockCode())
                            .stockType(dictService.getDictDataLabel(DictConst.STOCK_TYPE.getValue(), stock.getStockType()))
                            .locationCode(stock.getLocationId()==null?null:locationManager.queryLocation(stock.getLocationId()).getLocationCode())
                            .disabledFlag(stock.getDisabledFlag() ? "启用" : "禁用")
                            .build(),
                    StockVO::getStockId,
                    2000,
                    (processed, progress) -> exportTaskService.updateProgress(taskId, progress)
            );
        } catch (Exception e) {
           log.error("导出失败", e);
            exportTaskService.updateProgress(taskId, -1);
        } finally {
            exportTaskService.updateProgress(taskId, 100);
        }
    }
}
