package com.usky.iot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.iot.domain.PmProject;
import com.usky.iot.domain.PmWorkContent;
import com.usky.iot.mapper.PmProjectMapper;
import com.usky.iot.mapper.PmWorkContentMapper;
import com.usky.iot.mapper.SysUserMapper;
import com.usky.iot.service.PmProjectService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.system.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 项目表 服务实现类
 * </p>
 *
 * @author fu
 * @since 2024-05-20
 */
@Service
public class PmProjectServiceImpl extends AbstractCrudService<PmProjectMapper, PmProject> implements PmProjectService {

    @Autowired
    private PmWorkContentMapper pmWorkContentMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PmProjectMapper pmProjectMapper;

    @Override
    public void addProject(PmProject project) {
        if (Objects.isNull(project.getProjectWorkload())) {
            if (Objects.isNull(project.getId())) {
                project.setCreateBy(SecurityUtils.getUsername());
                project.setCreateTime(LocalDateTime.now());
                project.setTenantId(SecurityUtils.getTenantId());
                project.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
                this.save(project);
            } else {
                project.setUpdateBy(SecurityUtils.getUsername());
                project.setUpdateTime(LocalDateTime.now());
                this.updateById(project);
            }
        } else {
            if (project.getProjectWorkload().scale() > 2) {
                throw new BusinessException("计划人/天小数位超出长度请重新输入");
            } else if (project.getProjectWorkload().precision() - project.getProjectWorkload().scale() > 4) {
                throw new BusinessException("计划人/天整数位超出长度请重新输入");
            } else {
                if (Objects.isNull(project.getId())) {
                    project.setCreateBy(SecurityUtils.getUsername());
                    project.setCreateTime(LocalDateTime.now());
                    project.setTenantId(SecurityUtils.getTenantId());
                    project.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
                    this.save(project);
                } else {
                    project.setUpdateBy(SecurityUtils.getUsername());
                    project.setUpdateTime(LocalDateTime.now());
                    this.updateById(project);
                }
            }
        }
    }

    @Override
    public void delProject(Integer projectId) {
        LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PmWorkContent::getProjectId, projectId);
        List<PmWorkContent> pmWorkContent = pmWorkContentMapper.selectList(queryWrapper);
        if (pmWorkContent.size() != 0) {
            throw new BusinessException("该项目下存在日报，无法删除！");
        } else {
            LambdaQueryWrapper<PmProject> query = Wrappers.lambdaQuery();
            query.eq(PmProject::getId, projectId);
            PmProject project = baseMapper.selectOne(query);
            project.setDelFlag(1);
            project.setUpdateBy(SecurityUtils.getUsername());
            project.setUpdateTime(LocalDateTime.now());
            baseMapper.updateById(project);
        }
    }

    /**
     * 添加工作报告下拉框
     * 查询当前租户所有项目
     *
     * @return 只返回项目id和名称
     */
    @Override
    public List<PmProject> queryProject() {
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmProject::getId, PmProject::getProjectName)
                .eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                .eq(PmProject::getDelFlag, 0)
                .and(qw -> qw
                        .eq(PmProject::getProjectHead, SecurityUtils.getUserId())
                        .or().apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0")
                )
                .in(PmProject::getProjectStatus, 1, 2, 3);
        List<PmProject> list = this.list(wrapper);
        return list;
    }

    /**
     * 分页
     *
     * @param projectName       项目名
     * @param projectType       类型
     * @param projectStatus     状态
     * @param projectAscription 项目归属类型
     * @param pageNum           页码
     * @param pageSize          页大小
     * @return
     */
    @Override
    public CommonPage<PmProject> projectList(String projectName, Integer projectType, Integer projectStatus, Integer projectAscription, Integer pageNum, Integer pageSize) {
        IPage<PmProject> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PmProject> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                .eq(PmProject::getDelFlag, 0)
                .orderByDesc(PmProject::getCreateTime);
        if (projectAscription == 0) {
            lambdaQuery.and(q -> q.eq(PmProject::getProjectHead, SecurityUtils.getUserId())
                    .or().apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0")
                    .or().eq(PmProject::getCreateBy, SecurityUtils.getUsername()));
        } else if (projectAscription == 1) {
            lambdaQuery.eq(PmProject::getProjectHead, SecurityUtils.getUserId());
        } else if (projectAscription == 2) {
            lambdaQuery.apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0");
        }
        if (!projectName.isEmpty()) {
            lambdaQuery.like(PmProject::getProjectName, projectName);
        }
        if (projectType != 0) {
            lambdaQuery.eq(PmProject::getProjectType, projectType);
        }
        if (projectStatus != 0) {
            lambdaQuery.eq(PmProject::getProjectStatus, projectStatus);
        }
        page = this.page(page, lambdaQuery);
        if (page.getRecords() == null || page.getRecords().isEmpty()) {
            return new CommonPage<>(Collections.emptyList(), 0, pageSize, pageNum);
        }
        return new CommonPage<>(page.getRecords(), page.getTotal(), pageSize, pageNum);
    }

    /**
     * 查询项目名
     *
     * @param projectIds
     * @return
     */
    @Override
    public List<PmProject> projectName(List<Integer> projectIds) {
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmProject::getId, PmProject::getProjectName)
                .in(PmProject::getId, projectIds);
        return this.list(wrapper);
    }

    /**
     * 统计
     *
     * @return
     */
    @Override
    public Map<String, Integer> sum() {
        LambdaQueryWrapper<PmProject> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                .and(q -> q.eq(PmProject::getProjectHead, SecurityUtils.getUserId())
                        .or().apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0")
                        .or().eq(PmProject::getCreateBy, SecurityUtils.getUsername()))
                .eq(PmProject::getDelFlag, 0);
        Integer all = this.count(lambdaQuery);

        LambdaQueryWrapper<PmProject> lambdaQuery1 = Wrappers.lambdaQuery();
        lambdaQuery1.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                .eq(PmProject::getDelFlag, 0)
                .eq(PmProject::getProjectHead, SecurityUtils.getUserId());
        Integer head = this.count(lambdaQuery1);

        LambdaQueryWrapper<PmProject> lambdaQuery2 = Wrappers.lambdaQuery();
        lambdaQuery2.eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                .eq(PmProject::getDelFlag, 0)
                .apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0");
        Integer join = this.count(lambdaQuery2);

        Map<String, Integer> sumMap = new HashMap<>();
        sumMap.put("allProject", all);
        sumMap.put("headProject", head);
        sumMap.put("joinProject", join);
        return sumMap;
    }


    /**
     * 查询所有项目负责人、成员和userid（此处逻辑为查询所有项目中的负责人、团队成员然后进行去重）
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> projectUsers(Long userId) {
        List<Map<String, Object>> returnList = new ArrayList<>();
        List<SysUser> userList = new ArrayList<>();
        if (userId != null) {
            LambdaQueryWrapper<SysUser> queryNameId = Wrappers.lambdaQuery();
            queryNameId.select(SysUser::getUserId,SysUser::getNickName)
                    .eq(SysUser::getUserId, userId);
            userList = sysUserMapper.selectList(queryNameId);
        }else{
            LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
            wrapper.select(PmProject::getProjectHead, PmProject::getProjectMember)
                    .eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                    .eq(PmProject::getDelFlag, 0);
            List<PmProject> users = pmProjectMapper.selectList(wrapper);
            List<Long> userIds = new ArrayList<>();
            for (PmProject user : users) {
                Long projectHead = user.getProjectHead();
                userIds.add(projectHead);
                Set<Long> projectMembers = Arrays.stream(user.getProjectMember().split(","))
                        .map(Long::parseLong)
                        .collect(Collectors.toSet());
                userIds.addAll(projectMembers);
            }
            List<Long> finalList = userIds.stream().distinct().collect(Collectors.toList());
            LambdaQueryWrapper<SysUser> wrapper2 = Wrappers.lambdaQuery();
            wrapper2.select(SysUser::getUserId, SysUser::getNickName)
                    .in(SysUser::getUserId, finalList);
            userList = sysUserMapper.selectList(wrapper2);
        }
        for (SysUser user : userList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", user.getUserId());
            map.put("name", user.getNickName());
            returnList.add(map);
        }
        return returnList;
    }

    /**
     * 查询所有项目和id
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> projectIdName(Integer projectId) {
        List<Map<String, Object>> returnList = new ArrayList<>();
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmProject::getId, PmProject::getProjectName)
                .eq(PmProject::getTenantId, SecurityUtils.getTenantId())
                .eq(PmProject::getDelFlag, 0);
        if (projectId != null) {
            wrapper.eq(PmProject::getId, projectId);
        }
        List<PmProject> projects = pmProjectMapper.selectList(wrapper);
        for (PmProject project : projects) {
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("id", project.getId());
            returnMap.put("name", project.getProjectName());
            returnList.add(returnMap);
        }
        return returnList;
    }

    /**
     * @param identifying 标识：1，返回人员userId和nickName；2：返回ProjectId和ProjectName
     * @return
     */
    @Override
    public List<Map<String, Object>> userOrProject(Integer identifying) {
        Integer projectId = null;
        Long userId = null;
        List<Map<String, Object>> returnList = new ArrayList<>();
        if (identifying == 1) {
            returnList = projectUsers(userId);
        } else if (identifying == 2) {
            returnList = projectIdName(projectId);
        }
        return returnList;
    }

}
