package net.lab1024.sa.admin.module.business.base.location.service;

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 net.lab1024.sa.admin.constant.UsageStatusEnum;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.form.AreaSelect;
import net.lab1024.sa.admin.module.business.base.area.manager.AreaManager;
import net.lab1024.sa.admin.module.business.base.area.service.AreaQueryService;
import net.lab1024.sa.admin.module.business.base.location.dao.LocationDao;
import net.lab1024.sa.admin.module.business.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationQueryForm;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationSelect;
import net.lab1024.sa.admin.module.business.base.location.domain.form.LocationsExcelVO;
import net.lab1024.sa.admin.module.business.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.base.location.manager.LocationManager;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.util.SmartEnumUtil;
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.stream.Collectors;

@Service
public class LocationQueryService {

    @Resource
    private LocationDao locationDao;

    @Resource
    private AreaManager areaManager;

    @Resource
    private LocationManager locationManager;

    @Resource
    private AreaQueryService areaQueryService;

    @Resource
    private DictService dictService;

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

        // 查询库区名称
        List<Long> areaIdList = list.stream().map(LocationVO::getAreaId).distinct().collect(Collectors.toList());
        Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(areaIdList);
        list.forEach(locationVO -> {
            AreaEntity area = areaMap.get(locationVO.getAreaId());
            if (area != null) {
                locationVO.setAreaName(area.getAreaName());
            }
        });
        return SmartPageUtil.convert2PageResult(page, list);
    }

    /**
     * 实体转VO
     *
     * @param entity 实体
     * @return LocationVO
     */
    public LocationVO entityToVO(LocationEntity entity) {
        AreaEntity area = areaManager.queryArea(entity.getAreaId());
        return LocationVO.builder()
                .locationId(entity.getLocationId())
                .locationCode(entity.getLocationCode())
                .status(entity.getStatus())
                .areaId(entity.getAreaId())
                .areaName(area == null ? null : area.getAreaName())
                .disabledFlag(entity.getDisabledFlag())
                .locationRow(entity.getLocationRow())
                .locationLine(entity.getLocationLine())
                .locationCow(entity.getLocationCow())
                .locationType(entity.getLocationType())
                .remark(entity.getRemark())
                .createTime(entity.getCreateTime())
                .build();
    }


    /**
     * 库位下拉查询
     *
     * @param locationSelect 查询参数
     * @return List<LocationVO>
     */
    public List<LocationVO> queryLocation(LocationSelect locationSelect) {
        LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
        //是否启用
        if (locationSelect.getDisabledFlag() != null) {
            queryWrapper.eq(LocationEntity::getDisabledFlag, locationSelect.getDisabledFlag());
        }
        //库区
        if (CollectionUtils.isNotEmpty(locationSelect.getAreaNames())) {
            AreaSelect areaSelect = AreaSelect.builder().areaNames(locationSelect.getAreaNames()).build();
            areaSelect.setAreaNames(locationSelect.getAreaNames());
            List<AreaEntity> areaList = areaQueryService.queryArea(areaSelect);
            if (CollectionUtils.isNotEmpty(areaList)) {
                List<Long> areaIdList = areaList.stream().map(AreaEntity::getAreaId).collect(Collectors.toList());
                queryWrapper.in(LocationEntity::getAreaId, areaIdList);
            }
        }

        //库位类型
        if (StringUtils.isNotBlank(locationSelect.getLocationType())) {
            queryWrapper.eq(LocationEntity::getLocationType, locationSelect.getLocationType());
        }

        //库位状态
        if (StringUtils.isNotBlank(locationSelect.getStatus())) {
            queryWrapper.eq(LocationEntity::getStatus, locationSelect.getStatus());
        }

        List<LocationEntity> list = locationDao.selectList(queryWrapper);

        return list.stream().map(this::entityToVO).collect(Collectors.toList());
    }

    /**
     * 根据库位ID集合查询库位信息
     *
     * @param locationIdList 库位ID集合
     * @return Map<Long, LocationEntity>
     */
    public Map<Long, LocationEntity> queryLocationList(List<Long> locationIdList) {
        if (CollectionUtils.isEmpty(locationIdList)) {
            return Collections.emptyMap();
        }
        locationIdList = locationIdList.stream().distinct().collect(Collectors.toList());
        Map<Long, LocationEntity> locationMap = Maps.newHashMap();
        for (Long locationId : locationIdList) {
            LocationEntity location = locationManager.queryLocation(locationId);
            if (location != null) {
                locationMap.put(locationId, location);
            }
        }
        return locationMap;
    }

    /**
     * 验证库区是否存在库位
     *
     * @param areaId 库区
     */
    public Boolean checkLocationExist(Long areaId) {
        LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LocationEntity::getAreaId, areaId);
        List<LocationEntity> list = locationDao.selectList(queryWrapper);
        return list.isEmpty();
    }

    /**
     * 根据库位编码查询库位信息
     *
     * @param locationCode 库位编码
     * @return LocationEntity
     */
    public LocationEntity queryByLocationCode(String locationCode) {
        LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LocationEntity::getLocationCode, locationCode);
        return locationDao.selectOne(queryWrapper);
    }

    /**
     * 根据库位编码集合查询库位信息
     *
     * @param locationCodes 库位编码集合
     * @return List<LocationEntity>
     */
    public List<LocationEntity> queryByLocationCodes(List<String> locationCodes) {
        LambdaQueryWrapper<LocationEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(LocationEntity::getLocationCode, locationCodes);
        return locationDao.selectList(queryWrapper);
    }

    /**
     * 根据库位编码集合查询库位信息
     *
     * @param locationCodes 库位集合
     * @return Map<String, LocationEntity>
     */
    public Map<String, LocationEntity> queryLocationListToMap(List<String> locationCodes) {
        if (CollectionUtils.isEmpty(locationCodes)) {
            return Collections.emptyMap();
        }
        List<LocationEntity> locations = queryByLocationCodes(locationCodes);
        return locations.stream()
                .collect(Collectors.toMap(LocationEntity::getLocationCode, location -> location, (existing, replacement) -> existing));

    }

    /**
     * 库位导出
     *
     * @return List<LocationsExcelVO>
     */
    public List<LocationsExcelVO> getLocationsExcelVOList() {
        List<LocationEntity> locationsList = locationDao.selectList(null);
        //库区
        List<Long> areaIds = locationsList.stream().map(LocationEntity::getAreaId).distinct().collect(Collectors.toList());
        Map<Long, AreaEntity> areaMap = areaQueryService.queryAreaList(areaIds);
        return locationsList.stream()
                .map(location ->
                        LocationsExcelVO.builder()
                                .areaName(areaMap.get(location.getAreaId()).getAreaName())
                                .locationCode(location.getLocationCode())
                                .locationType(dictService.getDictDataLabel(DictConst.LOC_TYPE.getValue(), location.getLocationType()))
                                .status(SmartEnumUtil.getEnumDescByValue(location.getStatus(), UsageStatusEnum.class))
                                .disabledFlag(location.getDisabledFlag() ? "启用" : "禁用")
                                .build()
                )
                .collect(Collectors.toList());

    }


}
