package cn.iocoder.yudao.module.mes.service.workteam;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.workteam.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.workteam.WorkTeamDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.workteam.WorkTeamDetailDO;
import cn.iocoder.yudao.module.mes.dal.mysql.workteam.WorkTeamDetailMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.workteam.WorkTeamMapper;
import cn.iocoder.yudao.module.mes.service.organization.OrganizationService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WORK_TEAM_DETAIL_NOT_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WORK_TEAM_NOT_EXISTS;

/**
 * 生产班组 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class WorkTeamServiceImpl implements WorkTeamService {

    @Resource
    private WorkTeamMapper workTeamMapper;
    @Resource
    private WorkTeamDetailMapper workTeamDetailMapper;
    @Resource
    private OrganizationService organizationService;
    @Override
    public Long createWorkTeam(WorkTeamSaveReqVO createReqVO) {
        // 插入
        WorkTeamDO workTeam = BeanUtils.toBean(createReqVO, WorkTeamDO.class);
        workTeamMapper.insert(workTeam);
        // 返回
        return workTeam.getId();
    }

    @Override
    public void updateWorkTeam(WorkTeamSaveReqVO updateReqVO) {
        // 校验存在
        validateWorkTeamExists(updateReqVO.getId());
        // 更新
        WorkTeamDO updateObj = BeanUtils.toBean(updateReqVO, WorkTeamDO.class);
        workTeamMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteWorkTeam(Long id) {
        // 校验存在
        validateWorkTeamExists(id);
        // 删除
        workTeamMapper.deleteById(id);

        // 删除子表
        deleteWorkTeamDetailByWorkTeamId(id);
    }

    private void validateWorkTeamExists(Long id) {
        if (workTeamMapper.selectById(id) == null) {
            throw exception(WORK_TEAM_NOT_EXISTS);
        }
    }

    @Override
    public WorkTeamDO getWorkTeam(Long id) {
        return workTeamMapper.selectById(id);
    }

    @Override
    public PageResult<WorkTeamRespVO> getWorkTeamPage(WorkTeamPageReqVO pageReqVO) {
        PageResult<WorkTeamDO> pageResult = workTeamMapper.selectPage(pageReqVO);
        return new PageResult<>(buildVOList(pageResult.getList()), pageResult.getTotal());
    }
    @Resource
    private AdminUserApi adminUserApi;
    private List<WorkTeamRespVO> buildVOList(List<WorkTeamDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 1.4 成员信息
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                convertSet(list, WorkTeamDO::getTeamLeaderId));
        return BeanUtils.toBean(list, WorkTeamRespVO.class, item -> {
            MapUtils.findAndThen(userMap, item.getTeamLeaderId(),
                    user -> item.setTeamLeaderName(user.getNickname()));

        });
    }
    // ==================== 子表（班组成员） ====================

    @Override
    public PageResult<WorkTeamDetailRespVO> getWorkTeamDetailPage(PageParam pageReqVO, Long workTeamId) {

        PageResult<WorkTeamDetailDO> pageResult = workTeamDetailMapper.selectPage(pageReqVO, workTeamId);
        return new PageResult<>(buildDetailVOList(pageResult.getList()), pageResult.getTotal());
    }
    private List<WorkTeamDetailRespVO> buildDetailVOList(List<WorkTeamDetailDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 1.4 成员信息
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                convertSet(list, WorkTeamDetailDO::getUserId));
        return BeanUtils.toBean(list, WorkTeamDetailRespVO.class, item -> {
            MapUtils.findAndThen(userMap, item.getUserId(),
                    user -> item.setUserName(user.getUsername()).setNickName(user.getNickname()));
        });
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createWorkTeamDetail(WorkTeamDetailDO workTeamDetail) {

        WorkTeamDetailDO zuzhang = new WorkTeamDetailDO().setWorkTeamId(workTeamDetail.getWorkTeamId());
        if(workTeamDetail.getUserRole().equals(WorkTeamUserRoleEnum.组长.getValue())){
            //同一个组不能有多个组长
            zuzhang.setUserRole(workTeamDetail.getUserRole());
            if(teamUserRoleExists(zuzhang))
                throw exception(new ErrorCode(500,"该班组已存在组长，请先取消其他组长角色！"));
            zuzhang.setUserRole(null);
            WorkTeamDO teamDO = workTeamMapper.selectById(workTeamDetail.getWorkTeamId());
            if(teamDO!=null){
                teamDO.setTeamLeaderId(workTeamDetail.getUserId());
                workTeamMapper.updateById(teamDO);
            }
        }
        //同一个组不能有同一个人
        zuzhang.setUserId(workTeamDetail.getUserId());
        if(teamUserRoleExists(zuzhang))
            throw exception(new ErrorCode(500,"保存失败！该班组已存该成员！"));
        workTeamDetailMapper.insert(workTeamDetail);
        return workTeamDetail.getId();
    }
    //验证是否已存在
    private Boolean teamUserRoleExists(WorkTeamDetailDO workTeamDetail) {
        List<WorkTeamDetailDO> list = workTeamDetailMapper.selectBy(workTeamDetail);
        if ( list== null || list.size()==0) {
           return false;
        }
        return true;
    }
    @Override
    public void updateWorkTeamDetail(WorkTeamDetailDO workTeamDetail) {
        // 校验存在
        validateWorkTeamDetailExists(workTeamDetail.getId());
        WorkTeamDetailDO old = workTeamDetailMapper.selectById(workTeamDetail.getId());

        //由工人变组长
        if(workTeamDetail.getUserRole().equals(WorkTeamUserRoleEnum.组长.getValue())
        && old.getUserRole().equals(WorkTeamUserRoleEnum.工人.getValue()) ){
            WorkTeamDetailDO zuzhang = new WorkTeamDetailDO().setWorkTeamId(workTeamDetail.getWorkTeamId());

            //同一个组不能有多个组长
            zuzhang.setUserRole(workTeamDetail.getUserRole());
            if(teamUserRoleExists(zuzhang))
                throw exception(new ErrorCode(500,"该班组已存在组长，请先取消其他组长角色！"));
            //更新WorkTeamDO组长
            WorkTeamDO teamDO = workTeamMapper.selectById(workTeamDetail.getWorkTeamId());
            if(teamDO!=null){
                teamDO.setTeamLeaderId(workTeamDetail.getUserId());
                workTeamMapper.updateById(teamDO);
            }
        }

        // 更新
        workTeamDetailMapper.updateById(workTeamDetail);
    }

    @Override
    public void deleteWorkTeamDetail(Long id) {
        // 校验存在
        validateWorkTeamDetailExists(id);
        // 删除
        workTeamDetailMapper.deleteById(id);
    }
    @Override
    public List<WorkTeamDO> selectBy(WorkTeamDO detailDO){
        return workTeamMapper.selectBy(detailDO);
    }
    @Override
    public WorkTeamDetailDO getWorkTeamDetail(Long id) {
        return workTeamDetailMapper.selectById(id);
    }

    private void validateWorkTeamDetailExists(Long id) {
        if (workTeamDetailMapper.selectById(id) == null) {
            throw exception(WORK_TEAM_DETAIL_NOT_EXISTS);
        }
    }

    private void deleteWorkTeamDetailByWorkTeamId(Long workTeamId) {
        workTeamDetailMapper.deleteByWorkTeamId(workTeamId);
    }

    //获取某类型工序的所有成员
    @Override
    public List<WorkTeamDetailDO> getProcessUsers(String processType, String groupType) {
        WorkTeamDO teamDO = new WorkTeamDO().setTeamType(processType).setGroupType(groupType).setIsEnable(true);
        List<WorkTeamDO> list = workTeamMapper.selectBy(teamDO);
        if ( list!= null && list.size() > 0) {
            List<Long> idList = list.stream() // 将list转换为stream
                    .map(WorkTeamDO::getId) // 使用map操作，通过方法引用提取id
                    .collect(Collectors.toList()); // 通过collect操作，将结果转换为List
            List<WorkTeamDetailDO> detailDOList = workTeamDetailMapper.selectByTeamId(idList);
            return detailDOList;
        }
        return new ArrayList<>();
    }
    /**
     * 通过工序类型 查询工人
     *
     * @param processType 工序类型
     * @return 用户对象信息
     */
    @Override
    public List<AdminUserRespDTO> getUserList(String processType , String groupType){
        //班组和工序没关系了
        List<WorkTeamDetailDO> list = getProcessUsers(null, groupType);
        List<Long> idList = list.stream() // 将list转换为stream
                .map(WorkTeamDetailDO::getUserId)
                .collect(Collectors.toList());
        return adminUserApi.getUserList(idList);
    }
    @Override
    public List<AdminUserRespDTO> getUserList2(Long orgId , String groupType){
        //班组和工序没关系了
//        if(orgId == null)return null;
//        OrganizationDO organizationDO = organizationService.getOrganization(orgId);
//        if(organizationDO==null || StringUtils.isEmpty(organizationDO.getOrgType()))return null;

        List<WorkTeamDetailDO> list = getProcessUsers( null, groupType);
        List<Long> idList = list.stream() // 将list转换为stream
                .map(WorkTeamDetailDO::getUserId)
                .collect(Collectors.toList());
        return adminUserApi.getUserList(idList);
    }

    @Override
    public List<WorkTeamDetailDO> getUserWorkTeamDetail(Long workerId, Integer userRole){
        return workTeamDetailMapper.getUserWorkTeamDetail(workerId,userRole);
    }
    @Override
    public List<WorkTeamDO> selectByIds(List<Long> ids){
        return workTeamMapper.selectByIds(ids);
    }
    @Override
    public List<WorkTeamDetailDO> getDetailByWorkTeamIds(List<Long> workerIds){
        return workTeamDetailMapper.getDetailByWorkTeamIds(workerIds);
    }
    @Override
    public List<WorkTeamDO> getList(WorkTeamDO workTeamDO){
        return workTeamMapper.selectBy(workTeamDO);
    }
}