package org.dromara.work.service.impl;

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.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.work.domain.TpClient;
import org.dromara.work.domain.TpClientStaff;
import org.dromara.work.domain.bo.TpClientStaffBo;
import org.dromara.work.domain.vo.TpClientStaffVo;
import org.dromara.work.mapper.TpClientMapper;
import org.dromara.work.mapper.TpClientStaffMapper;
import org.dromara.work.service.ITpClientStaffService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 客户+客服Service业务层处理
 *
 * @author Maosw
 * @date 2024-08-12
 */
@RequiredArgsConstructor
@Service
public class TpClientStaffServiceImpl extends MPJBaseServiceImpl<TpClientStaffMapper, TpClientStaff> implements ITpClientStaffService {

    private final TpClientStaffMapper baseMapper;

    private final TpClientMapper tpClientMapper;

    private final SysUserMapper sysUserMapper;

    /**
     * 查询客户+客服
     *
     * @param id 主键
     * @return 客户+客服
     */
    @Override
    public TpClientStaffVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询客户+客服列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 客户+客服分页列表
     */
    @Override
    public TableDataInfo<TpClientStaffVo> queryPageList(TpClientStaffBo bo, PageQuery pageQuery) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(!LoginHelper.isSuperAdmin()){
            bo.setSid(loginUser.getUserId());
        }
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpClientStaff> wrapper = buildQueryMPJWrapper(bo)
            .selectAll(TpClientStaff.class)
            .selectAs(TpClient::getPhone,TpClientStaffVo::getPhone)
            .selectAs(TpClient::getCode,TpClientStaffVo::getCode)
            .leftJoin(TpClient.class,TpClient::getId,TpClientStaff::getKid)
            .eq(TpClientStaff::getIsDel,1)
            .orderByDesc(TpClientStaff::getId);

        //分页查询 （需要启用 mybatis plus 分页插件）
        IPage<TpClientStaffVo> listPage = baseMapper.selectJoinPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), TpClientStaffVo.class, wrapper);
        return TableDataInfo.build(listPage);
    }

    /**
     * 查询符合条件的客户+客服列表
     *
     * @param bo 查询条件
     * @return 客户+客服列表
     */
    @Override
    public List<TpClientStaffVo> queryList(TpClientStaffBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(!LoginHelper.isSuperAdmin()){
            bo.setSid(loginUser.getUserId());
        }
        //和Mybatis plus一致，MPJLambdaWrapper的泛型必须是主表的泛型，并且要用主表的Mapper来调用
        MPJLambdaWrapper<TpClientStaff> wrapper = buildQueryMPJWrapper(bo)
            .selectAll(TpClientStaff.class)
            .selectAs(TpClient::getPhone,TpClientStaffVo::getPhone)
            .selectAs(TpClient::getCode,TpClientStaffVo::getCode)
            .leftJoin(TpClient.class,TpClient::getId,TpClientStaff::getKid)
            .eq(TpClientStaff::getIsDel,1)
            .orderByDesc(TpClientStaff::getId);
        return baseMapper.selectVoList(wrapper);
    }

    private MPJLambdaWrapper<TpClientStaff> buildQueryMPJWrapper(TpClientStaffBo bo) {
        Map<String, Object> params = bo.getParams();
        MPJLambdaWrapper<TpClientStaff> lqw = new MPJLambdaWrapper<>();
        lqw.eq(bo.getSid() != null, TpClientStaff::getSid, bo.getSid());
        lqw.eq(bo.getKid() != null, TpClientStaff::getKid, bo.getKid());
        lqw.like(StringUtils.isNotBlank(bo.getName()), TpClientStaff::getName, bo.getName());
        lqw.like(StringUtils.isNotBlank(bo.getCode()), TpClient::getCode, bo.getCode());
        lqw.like(StringUtils.isNotBlank(bo.getPhone()), TpClient::getPhone, bo.getPhone());
        lqw.eq(bo.getYue() != null, TpClientStaff::getYue, bo.getYue());
        lqw.eq(bo.getAddTime() != null, TpClientStaff::getAddTime, bo.getAddTime());
        return lqw;
    }

    /**
     * 新增客户+客服
     *
     * @param bo 客户+客服
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TpClientStaffBo bo) {
        TpClientStaff add = MapstructUtils.convert(bo, TpClientStaff.class);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改客户+客服
     *
     * @param bo 客户+客服
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TpClientStaffBo bo) {
        TpClientStaff update = MapstructUtils.convert(bo, TpClientStaff.class);
        baseMapper.updateById(update);
        TpClient tpClient = tpClientMapper.selectById(update.getKid());
        BigDecimal zYue = baseMapper.selectList(new LambdaQueryWrapper<TpClientStaff>().eq(TpClientStaff::getKid, tpClient.getId()).eq(TpClientStaff::getIsDel, 1)).stream().map(TpClientStaff::getYue).reduce(BigDecimal.ZERO, BigDecimal::add);
        tpClient.setYue(zYue);
        return  tpClientMapper.updateById(tpClient) > 0;
    }


    /**
     * 校验并批量删除客户+客服信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        TpClientStaffVo tpClientStaffVo = baseMapper.selectVoById(ids.iterator().next());
        baseMapper.deleteByIds(ids);
        TpClient tpClient = tpClientMapper.selectById(tpClientStaffVo.getKid());
        List<Long> sids = baseMapper.selectList(new MPJLambdaWrapper<TpClientStaff>().eq(TpClientStaff::getKid, tpClient.getId()).eq(TpClientStaff::getIsDel, 1)).stream().map(TpClientStaff::getSid).collect(Collectors.toList());
        if(sids != null && sids.size() > 0){
            List<String> nameList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getUserId, sids)).stream().map(SysUser::getNickName).collect(Collectors.toList());
            tpClient.setSname(StringUtils.join(nameList, ","));
        }else {
            tpClient.setSname(null);
        }
        return tpClientMapper.updateById(tpClient) > 0;
    }
}
