package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.shkj.common.annotation.DataScopeConsignor;
import com.shkj.common.core.domain.Result;
import com.shkj.common.core.domain.entity.BaseBranch;
import com.shkj.common.enums.IsDelEnum;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.wms.domain.BaseStorage;
import com.shkj.wms.mapper.BaseStorageMapper;
import com.shkj.wms.service.IBaseStorageService;
import com.shkj.wms.bo.BaseStorageQueryBo;
import com.shkj.wms.bo.BaseStorageQueryListBo;
import com.shkj.wms.bo.BaseStorageSaveOrUpdateBo;
import com.shkj.wms.config.ValidList;
import com.shkj.wms.vo.BaseStorageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 库别资料Service业务层处理
 *
 * @author lch
 * @date 2022-04-19
 */
@Slf4j
@Service
public class BaseStorageServiceImpl extends ServiceImpl<BaseStorageMapper, BaseStorage> implements IBaseStorageService {

    @Override
    public Result<BaseStorageVo> queryById(Long id) {
        BaseStorage db = this.baseMapper.selectById(id);
        BaseStorageVo vo = BeanUtil.toBean(db, BaseStorageVo.class);
        return Result.ok().data(vo);
    }

    @Override
    public List<BaseStorageVo> queryList(BaseStorageQueryBo bo) {
        LambdaQueryWrapper<BaseStorage> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getStorageType()), BaseStorage::getStorageType, bo.getStorageType());
        lqw.like(StrUtil.isNotBlank(bo.getStorageName()), BaseStorage::getStorageName, bo.getStorageName());
        lqw.eq(StrUtil.isNotBlank(bo.getExtend1()), BaseStorage::getExtend1, bo.getExtend1());
        lqw.eq(StrUtil.isNotBlank(bo.getExtend2()), BaseStorage::getExtend2, bo.getExtend2());
        lqw.eq(StrUtil.isNotBlank(bo.getExtend3()), BaseStorage::getExtend3, bo.getExtend3());
        lqw.eq(StrUtil.isNotBlank(bo.getExtend4()), BaseStorage::getExtend4, bo.getExtend4());
        lqw.eq(StrUtil.isNotBlank(bo.getExtend5()), BaseStorage::getExtend5, bo.getExtend5());
        lqw.eq(bo.getBranchId() != null, BaseStorage::getBranchId, SecurityUtils.getCurrentBranchId());
        lqw.eq(StrUtil.isNotBlank(bo.getIsDel()), BaseStorage::getIsDel, bo.getIsDel());
        lqw.eq(BaseStorage::getIsDel, IsDelEnum.NORMAL.getValue());
        lqw.orderByDesc(BaseStorage::getCreateTime);
        List<BaseStorageVo> voList = entity2Vo(this.list(lqw));
        return voList;
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<BaseStorageVo> entity2Vo(Collection<BaseStorage> collection) {
        List<BaseStorageVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, BaseStorageVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<BaseStorage> page = (Page<BaseStorage>) collection;
            Page<BaseStorageVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> deleteWithValidById(List<Long> ids, Boolean isValid) {
        BaseStorage del = new BaseStorage();
        del.setIsDel(IsDelEnum.DELETED.getValue());
        LambdaQueryWrapper<BaseStorage> wrapper = new LambdaQueryWrapper<BaseStorage>().in(BaseStorage::getId, ids)
                .eq(BaseStorage::getBranchId, SecurityUtils.getCurrentBranchId());
        this.update(del, wrapper);
        return Result.ok();
    }

    /**
     * 查询库别信息列表
     */
    @Override
    @DataScopeConsignor(branchAlias = "bs")
    public List<BaseStorageVo> queryBaseStorageList(BaseStorageQueryListBo bo) {
        return this.getBaseMapper().queryBaseStorageList(bo);
    }

    @Override
    public List<BaseStorageVo> queryBaseStorageListA(BaseStorageQueryListBo bo) {
        return this.getBaseMapper().queryBaseStorageListA(bo);
    }




    public List<BaseStorage> queryBaseStorageByCodes(List<String> codes) {
        LambdaQueryWrapper<BaseStorage> lqw = Wrappers.lambdaQuery();
        lqw.in(BaseStorage::getStorageCode, codes);
        lqw.eq(BaseStorage::getBranchId, SecurityUtils.getCurrentBranchId());
        lqw.eq(BaseStorage::getIsDel, IsDelEnum.NORMAL.getValue());
        lqw.orderByDesc(BaseStorage::getCreateTime);
        return list(lqw);
    }

    public List<BaseStorage> queryBaseStorageByIds(List<Long> ids) {
        LambdaQueryWrapper<BaseStorage> lqw = Wrappers.lambdaQuery();
        lqw.in(BaseStorage::getId, ids);
        lqw.eq(BaseStorage::getBranchId, SecurityUtils.getCurrentBranchId());
        lqw.eq(BaseStorage::getIsDel, IsDelEnum.NORMAL.getValue());
        lqw.orderByDesc(BaseStorage::getCreateTime);
        return list(lqw);
    }

    /**
     * 保存或者修改库别信息（根据是否有id来判断新增或者修改）
     *
     * @param list
     * @return
     */
    @Override
    public Result<Boolean> saveOrUpdateBaseStorage(ValidList<BaseStorageSaveOrUpdateBo> list) {
        List<BaseStorage> addList = new ArrayList<>();
        List<BaseStorage> updList = new ArrayList<>();

        Set<String> listGroup = list.stream().collect(Collectors.groupingBy(item ->
                item.getStorageCode())).keySet();
        if (listGroup.size() != list.size()) {
            log.error("请求参数存在重复数据！");
            return Result.err().msg("请求参数存在重复数据！");
        }

        for (BaseStorageSaveOrUpdateBo bo : list) {
            if (bo.getId() != null) {
                BaseStorage one = getById(bo.getId());
                if (one == null) {
                    log.info("库别信息不存在:" + bo.toString());
                    return Result.err().msg("库别信息不存在！");
                }

                BaseStorage update = BeanUtil.toBean(bo, BaseStorage.class);
                update.setBranchId(one.getBranchId());
                Result result = checkEntity(update);
                if (!Result.isOk(result)) {
                    return Result.err().msg(result.getMsg());
                }
                updList.add(update);
            } else {
                BaseStorage add = BeanUtil.toBean(bo, BaseStorage.class);
                add.setBranchId(SecurityUtils.getCurrentBranchId());
                Result result = checkEntity(add);
                if (!Result.isOk(result)) {
                    return Result.err().msg(result.getMsg());
                }
                addList.add(add);
            }
        }
        this.updateBatchById(updList);
        this.saveBatch(addList);
        return Result.ok();
    }

    @Override
    public List<BaseStorage> queryStorageList(Long branchId) {

        return list(new LambdaQueryWrapper<BaseStorage>()
                .eq(BaseStorage::getIsDel, IsDelEnum.NORMAL.getValue())
                .eq(BaseStorage::getBranchId, branchId)
                .orderByDesc(BaseStorage::getCreateTime));

    }

    /**
     * 校验数据 (相同工号、相同作业类型、作业顺序不允许重复)
     *
     * @param entity
     * @return
     */
    private Result checkEntity(BaseStorage entity) {
        Long id = entity.getId() != null ? entity.getId() : -1L;
        LambdaQueryWrapper<BaseStorage> wrapper = new LambdaQueryWrapper<BaseStorage>()
                .eq(BaseStorage::getBranchId, entity.getBranchId())
                .eq(BaseStorage::getStorageCode, entity.getStorageCode())
                .eq(BaseStorage::getIsDel, IsDelEnum.NORMAL.getValue());
        BaseStorage one = getOne(wrapper);
        if (one != null && !id.equals(one.getId())) {
            log.info("存在重复数据：" + entity.toString());
            return Result.err().msg("存在重复数据");
        }
        return Result.ok();
    }


    @Override
    public Result<Boolean> switchStatus(Long id, String status) {
        BaseStorage storage = new BaseStorage();
        storage.setId(id).setIsActivity(status);
        return this.updateById(storage) ? Result.ok() : Result.err();
    }
}
