package org.dromara.work.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
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.dto.RoleDTO;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
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.SysDept;
import org.dromara.system.domain.SysRoleDept;
import org.dromara.system.domain.SysUser;
import org.dromara.system.mapper.SysDeptMapper;
import org.dromara.system.mapper.SysRoleDeptMapper;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.work.domain.TpMonth;
import org.dromara.work.domain.bo.TpMonthBo;
import org.dromara.work.domain.vo.TpMonthVo;
import org.dromara.work.mapper.TpMonthMapper;
import org.dromara.work.service.ITpMonthService;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 月目标Service业务层处理
 *
 * @author Maosw
 * @date 2024-08-12
 */
@RequiredArgsConstructor
@Service
public class TpMonthServiceImpl extends MPJBaseServiceImpl<TpMonthMapper, TpMonth> implements ITpMonthService {

    private final TpMonthMapper baseMapper;

    private final SysDeptMapper deptMapper;

    private final SysUserMapper userMapper;

    private final SysRoleDeptMapper roleDeptMapper;

    /**
     * 查询月目标
     *
     * @param id 主键
     * @return 月目标
     */
    @Override
    public TpMonthVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询月目标列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 月目标分页列表
     */
    @Override
    public TableDataInfo<TpMonthVo> queryPageList(TpMonthBo bo, PageQuery pageQuery) {
        MPJLambdaWrapper<TpMonth> lqw = buildQueryWrapper(bo);
        lqw.selectAll(TpMonth.class)
            .selectAs(SysUser::getNickName, TpMonthVo::getNickName)
            .selectAs(SysUser::getRealName, TpMonthVo::getRealName)
            .selectAs(SysDept::getDeptName, TpMonthVo::getDeptName)
            .leftJoin(SysUser.class, SysUser::getUserId, TpMonth::getSid)
            .leftJoin(SysDept.class, SysDept::getDeptId, TpMonth::getDeptId)
            .orderByDesc(TpMonth::getId);

        IPage<TpMonthVo> result = baseMapper.selectJoinPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), TpMonthVo.class, lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的月目标列表
     *
     * @param bo 查询条件
     * @return 月目标列表
     */
    @Override
    public List<TpMonthVo> queryList(TpMonthBo bo) {
        MPJLambdaWrapper<TpMonth> lqw = buildQueryWrapper(bo);
        lqw.selectAll(TpMonth.class)
            .selectAs(SysUser::getNickName, TpMonthVo::getNickName)
            .selectAs(SysUser::getRealName, TpMonthVo::getRealName)
            .selectAs(SysDept::getDeptName, TpMonthVo::getDeptName)
            .leftJoin(SysUser.class, SysUser::getUserId, TpMonth::getSid)
            .leftJoin(SysDept.class, SysDept::getDeptId, TpMonth::getDeptId)
            .orderByDesc(TpMonth::getId);

        return baseMapper.selectJoinList(TpMonthVo.class,lqw);
    }

    private MPJLambdaWrapper<TpMonth> buildQueryWrapper(TpMonthBo bo) {
        MPJLambdaWrapper<TpMonth> lqw = new MPJLambdaWrapper<>();
        if(ObjectUtil.isNotNull(bo.getDeptId())){
            List<Long> deptIds = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().like(SysDept::getAncestors, bo.getDeptId())).stream().map(SysDept::getDeptId).collect(Collectors.toList());
            deptIds.add(bo.getDeptId());
            if (deptIds != null && deptIds.size() > 0){
                lqw.in(TpMonth::getDeptId, deptIds);
            }
        }/*else {
            LoginUser loginUser = LoginHelper.getLoginUser();
            int scope = getDataScope();
            if(scope == 2){
                List<Long> deptIds = getDeptIds();
                lqw.in(TpMonth::getDeptId,deptIds);
            }else if(scope == 3){
                lqw.eq(TpMonth::getDeptId,loginUser.getDeptId());
            }else if(scope == 4){
                List<Long> deptIds = deptMapper.selectList(new LambdaQueryWrapper<SysDept>().like(SysDept::getAncestors, loginUser.getDeptId())).stream().map(SysDept::getDeptId).collect(Collectors.toList());
                deptIds.add(loginUser.getDeptId());
                lqw.in(TpMonth::getDeptId,deptIds);
            }else if(scope == 5){
                lqw.eq(TpMonth::getSid,loginUser.getUserId());
            }
        }*/
        lqw.like(StringUtils.isNotBlank(bo.getNickName()), SysUser::getNickName, bo.getNickName());
        lqw.eq(bo.getSid() != null, TpMonth::getSid, bo.getSid());
        lqw.in(bo.getUserIds() != null, TpMonth::getSid, bo.getUserIds());
        lqw.eq(StringUtils.isNotBlank(bo.getMonth()), TpMonth::getMonth, bo.getMonth());
        lqw.eq(bo.getGeren() != null, TpMonth::getGeren, bo.getGeren());
        lqw.eq(bo.getGongsi() != null, TpMonth::getGongsi, bo.getGongsi());
        lqw.eq(bo.getAddTime() != null, TpMonth::getAddTime, bo.getAddTime());
        return lqw;
    }

    public int getDataScope() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        List<String> ids = loginUser != null ?
            loginUser.getRoles().stream().filter(Objects::nonNull).map(role -> role.getDataScope()).filter(Objects::nonNull).collect(Collectors.toList()) :
            Collections.emptyList();

        if (ids.contains("1")) {
            return 1;
        } else if (ids.contains("2")) {
            return 2;
        } else if (ids.contains("3")) {
            return 3;
        } else if (ids.contains("4")) {
            return 4;
        } else if (ids.contains("5")) {
            return 5;
        }
        return 0;
    }

    public List<Long> getDeptIds(){
        LoginUser loginUser = LoginHelper.getLoginUser();
        List<Long> roleIds = loginUser.getRoles().stream().map(RoleDTO::getRoleId).collect(Collectors.toList());
        List<Long> getDeptIds = roleDeptMapper.selectList(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, roleIds)).stream().map(SysRoleDept::getDeptId).collect(Collectors.toList());
        return getDeptIds.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 新增月目标
     *
     * @param bo 月目标
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TpMonthBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        String month = DateUtil.format(new Date(), "yyyy-MM");
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<TpMonth>().eq(TpMonth::getSid,bo.getSid()).eq(TpMonth::getMonth, bo.getMonth()));
        if (exists){
            throw new ServiceException("该用户已存在该月的目标，请勿重复添加！");
        }

//        bo.setSid(bo.getSid());
//        bo.setMonth(month);
        bo.setAddTime(new Date());

        SysDept dept = deptMapper.selectById(bo.getDeptId());
        bo.setDeptId(dept.getDeptId());
        bo.setAncestors(dept.getAncestors());

        TpMonth add = MapstructUtils.convert(bo, TpMonth.class);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改月目标
     *
     * @param bo 月目标
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TpMonthBo bo) {
        /*LoginUser loginUser = LoginHelper.getLoginUser();
        String month = DateUtil.format(new Date(), "yyyy-MM");
        TpMonth update = baseMapper.selectOne(new LambdaQueryWrapper<TpMonth>().eq(TpMonth::getSid,loginUser.getUserId()).eq(TpMonth::getMonth, month));
        if (update != null) {
            update.setGeren(bo.getGeren());
            update.setAddTime(new Date());
            return baseMapper.updateById(update) > 0;
        }

        bo.setSid(loginUser.getUserId());
        bo.setMonth(month);*/
        bo.setAddTime(new Date());
        TpMonth add = MapstructUtils.convert(bo, TpMonth.class);
        return baseMapper.updateById(add) > 0;
    }

    /**
     * 校验并批量删除月目标信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 根据用户和月份查询
     * @param monthBo
     * @return
     */
    @Override
    public TpMonthVo queryTpMonth(TpMonthBo monthBo) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<TpMonth>().eq(TpMonth::getSid, monthBo.getSid()).eq(TpMonth::getMonth, monthBo.getMonth()));
    }
}
