package com.shkj.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.shkj.common.core.domain.Result;
import com.shkj.common.core.domain.TreeBranchSelect;
import com.shkj.common.core.domain.entity.BaseConsignor;
import com.shkj.common.enums.IsDelEnum;
import com.shkj.common.utils.SecurityUtils;
import com.shkj.wms.bo.BaseConsignorQueryBo;
import com.shkj.wms.bo.BaseConsignorSaveOrUpdateBo;
import com.shkj.wms.common.SwitchStatusEntity;
import com.shkj.wms.enums.DeleteFlagEnum;
import com.shkj.wms.mapper.BaseConsignorMapper;
import com.shkj.wms.service.IBaseConsignorService;
import com.shkj.wms.vo.BaseConsignorVo;
import com.shkj.wms.vo.BranchTree;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
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-03-22
 */
@Slf4j
@Service
public class BaseConsignorServiceImpl extends ServiceImpl<BaseConsignorMapper, BaseConsignor> implements IBaseConsignorService {


    @Override
    public BaseConsignor getConsignorByCode(String consignorCode) {
        return this.getOne(new LambdaQueryWrapper<BaseConsignor>().eq(BaseConsignor::getConsignorCode, consignorCode)
                .eq(BaseConsignor::getIsDel, IsDelEnum.NORMAL.getValue()));
    }

    @Override
    public List<BaseConsignorVo> queryList(BaseConsignorQueryBo bo) {
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId())){
            bo.setBranchIds(new ArrayList<>());
            bo.setRolesId(new ArrayList<>());
            return this.baseMapper.queryList(bo);
        }
        List<Long> branchIds = SecurityUtils.getBranchIds();
        if (CollectionUtils.isEmpty(branchIds)) {
            branchIds = new ArrayList<>();
            branchIds.add(-1L);
        }
        bo.setBranchIds(branchIds);

        List<Long> rolesId = SecurityUtils.getLoginUser().getUser().getRoles().stream().map(x->x.getRoleId()).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(rolesId)) {
            rolesId = new ArrayList<>();
            rolesId.add(-1L);
        }
        bo.setRolesId(rolesId);
        return this.baseMapper.queryList(bo);
//        LambdaQueryWrapper<BaseConsignor> lqw = Wrappers.lambdaQuery();
//        if (StrUtil.isNotBlank(bo.getSearchValue())) {
//            lqw.and(x -> x.like(BaseConsignor::getConsignorCode, bo.getSearchValue()).or().like(BaseConsignor::getConsignorName, bo.getSearchValue()
//            ).or().like(BaseConsignor::getMnemonic, bo.getSearchValue()));
//        }
//        lqw.eq(BaseConsignor::getBranchId, SecurityUtils.getCurrentBranchId());
//        lqw.eq(BaseConsignor::getIsDel, IsDelEnum.NORMAL.getValue());
//        lqw.orderByDesc(BaseConsignor::getCreateTime);
//        List<BaseConsignorVo> voList = entity2Vo(this.list(lqw));
//        return voList;

    }

    @Override
    public List<BaseConsignorVo> queryListOption(BaseConsignorQueryBo bo) {
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId())){
            bo.setBranchIds(new ArrayList<>());
            bo.setRolesId(new ArrayList<>());
            return this.baseMapper.queryList(bo);
        }

        List<Long> branchIds = SecurityUtils.getBranchIds();
        if (CollectionUtils.isEmpty(branchIds)) {
            branchIds = new ArrayList<>();
            branchIds.add(-1L);
        }
        bo.setBranchIds(branchIds);
        bo.setRolesId(new ArrayList<>());
        return this.baseMapper.queryList(bo);

    }

    @Override
    public List<BranchTree> selectBranchConsignor() {
        if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
            return baseMapper.selectBranchConsignor(new ArrayList<>());
        } else {
            List<Long> branchIds = SecurityUtils.getBranchIds();
            //如果不是超级管理员、没有仓库权限
            if (CollectionUtils.isEmpty(branchIds)) {
                branchIds = new ArrayList<>();
                branchIds.add(-1L);
            }
            return baseMapper.selectBranchConsignor(branchIds);
        }

    }

    /**
     * 根据角色ID查询货主树信息
     *
     * @param roleId
     * @return
     */
    @Override
    public List<Long> selectConsignorListByRoleId(Long roleId) {
        return baseMapper.selectConsignorListByRoleId(roleId);
    }

    @Override
    public List<TreeBranchSelect> buildTreeSelect(List<BranchTree> treeList) {
        List<TreeBranchSelect> returnList = new ArrayList<>();
        for (BranchTree tree : treeList) {
            TreeBranchSelect select = new TreeBranchSelect();
            select.setId(tree.getBranchCode());
            select.setLabel(tree.getBranchName());


            List<BaseConsignor> consignors = tree.getBaseConsignors();
            List<TreeBranchSelect> sonList = new ArrayList<>();
            for (BaseConsignor consignor : consignors) {
                TreeBranchSelect son = new TreeBranchSelect();
                son.setId(consignor.getId().toString());
                son.setLabel(consignor.getConsignorName());
                sonList.add(son);
            }
            select.setChildren(sonList);
            returnList.add(select);
        }
        return returnList;
    }

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

    /**
     * 根据id和当前branchId获取货主数据
     *
     * @param ids
     * @param branchId 当前仓id
     * @return
     */
    @Override
    public List<BaseConsignor> queryBaseConsignorListByIdsAndBranchId(List<Long> ids, Long branchId) {
        LambdaQueryWrapper<BaseConsignor> wrapper = new LambdaQueryWrapper<BaseConsignor>()
                .in(BaseConsignor::getId, ids)
                .eq(BaseConsignor::getBranchId, SecurityUtils.getCurrentBranchId())
                .eq(BaseConsignor::getIsDel, DeleteFlagEnum.NORMAL.getValue());
        return this.list(wrapper);
    }

    /**
     * 保存或者修改复业主资料（根据是否有id来判断新增或者修改）
     * @param list
     * @return
     */
    @Override
    public Result<Boolean> saveOrUpdateBaseConsignors(List<BaseConsignorSaveOrUpdateBo> list) {
        List<BaseConsignor> addList = new ArrayList<>();
        List<BaseConsignor> updList = new ArrayList<>();

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

        for(BaseConsignorSaveOrUpdateBo bo:list){
            if(bo.getId() != null){
                BaseConsignor one = getById(bo.getId());
                if(one == null){
                    log.error("人员拣货权限不存在:"+bo.toString());
                    return Result.err().msg("货主不存在");
                }

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

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

    /**
     * 切换状态
     *
     * @param switchStatusEntity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Boolean> switchStatus(SwitchStatusEntity switchStatusEntity) {
        BaseConsignor status = new BaseConsignor();
        status.setId(switchStatusEntity.getId());
        status.setIsuse(switchStatusEntity.getIsuse());
        return this.updateById(status) ? Result.ok() : Result.err();
    }

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