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

import cn.hutool.core.collection.CollUtil;
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.organization.vo.OrgClassEnum;
import cn.iocoder.yudao.module.mes.controller.admin.organization.vo.OrganizationListReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.orgworker.vo.OrgWorkerPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.orgworker.vo.OrgWorkerRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.orgworker.vo.OrgWorkerSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.orgworker.OrgWorkerDO;
import cn.iocoder.yudao.module.mes.dal.mysql.orgworker.OrgWorkerMapper;
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.time.LocalDateTime;
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.ORG_WORKER_NOT_EXISTS;

/**
 * 工位安排 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class OrgWorkerServiceImpl implements OrgWorkerService {

    @Resource
    private OrgWorkerMapper orgWorkerMapper;
    @Resource
    private OrganizationService organizationService;

    @Resource
    private AdminUserApi adminUserApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrgWorker(OrgWorkerSaveReqVO createReqVO) {
        OrganizationDO organizationDO = organizationService.getOrganization(createReqVO.getOrgId());
        // 插入
        OrgWorkerDO orgWorker = BeanUtils.toBean(createReqVO, OrgWorkerDO.class);
        orgWorker.setOrgType(organizationDO.getOrgType());
        //多个日期
        if(createReqVO.getPlanDates()!=null && createReqVO.getPlanDates().length>0){
            //校验同工位、同班别、同日期是否已经存在，存在则替换保存
            OrgWorkerPageReqVO reqVO = new OrgWorkerPageReqVO()
                    .setOrgId(createReqVO.getOrgId())
                    .setGroupType(createReqVO.getGroupType());
            for (LocalDateTime date : createReqVO.getPlanDates()) {
                LocalDateTime[] dates = {date,date};
                reqVO.setWorkDate(dates);
                List<OrgWorkerDO> list = orgWorkerMapper.selectList(reqVO);
                //删掉旧的，增加新的替换
                if(list!=null && list.size()>0){
                    List<Long> ids = list.stream().map(OrgWorkerDO::getId).collect(Collectors.toList());
                    orgWorkerMapper.deleteBatchIds(ids);
                }
                orgWorker.setWorkDate(date);
                orgWorker.setId(null);
                orgWorkerMapper.insert(orgWorker);
            }
        }
        else  orgWorkerMapper.insert(orgWorker);
        // 返回
        return orgWorker.getId();
    }

    @Override
    public void updateOrgWorker(OrgWorkerSaveReqVO updateReqVO) {
        // 校验存在
        validateOrgWorkerExists(updateReqVO.getId());
        // 更新
        OrgWorkerDO updateObj = BeanUtils.toBean(updateReqVO, OrgWorkerDO.class);
        orgWorkerMapper.updateById(updateObj);
    }

    @Override
    public void deleteOrgWorker(Long id) {
        // 校验存在
        validateOrgWorkerExists(id);
        // 删除
        orgWorkerMapper.deleteById(id);
    }

    private void validateOrgWorkerExists(Long id) {
        if (orgWorkerMapper.selectById(id) == null) {
            throw exception(ORG_WORKER_NOT_EXISTS);
        }
    }

    @Override
    public OrgWorkerDO getOrgWorker(Long id) {
        return orgWorkerMapper.selectById(id);
    }

    @Override
    public PageResult<OrgWorkerRespVO> getOrgWorkerPage(OrgWorkerPageReqVO pageReqVO) {
        OrganizationListReqVO reqVO = new OrganizationListReqVO();
        boolean orgSearch = false;
        //查询某个工序及其下属工序
        if(pageReqVO.getOrgId()!=null){
            OrganizationDO organizationDO = organizationService.getOrganization(pageReqVO.getOrgId());
            if(organizationDO.getOrgClass().equals(OrgClassEnum.工序.getValue())){
                reqVO.setParentId(pageReqVO.getOrgId());
                List<OrganizationDO> orgList = organizationService.getOrganizationListNoParent(reqVO);
                if(orgList!=null && orgList.size()>0){
                    List<Long> ids = orgList.stream()
                            .map(OrganizationDO::getId)
                            .collect(Collectors.toList());
                    pageReqVO.setOrgIds(ids);
                    pageReqVO.setOrgId(null);
                }
            }
        }
        PageResult<OrgWorkerDO> pageResult = orgWorkerMapper.selectPage(pageReqVO);
        return new PageResult<>(buildVOList(pageResult.getList()),pageResult.getTotal());
    }

    @Override
    public List<OrgWorkerRespVO> buildVOList(List<OrgWorkerDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, OrganizationDO> map = organizationService.getMap(
                convertSet(list, OrgWorkerDO::getOrgId));
        // 1.4 管理员信息
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                convertSet(list, OrgWorkerDO::getWorkerId));
        return BeanUtils.toBean(list, OrgWorkerRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getOrgId(),
                    org -> item.setOrgName(org.getName()).setOrgType(org.getOrgType())
            );
            MapUtils.findAndThen(userMap, item.getWorkerId(),
                    user -> item.setWorkerName(user.getNickname()));

            MapUtils.findAndThen(userMap, Long.valueOf(item.getCreator()),
                    user -> item.setCreator(user.getNickname()));
        });
    }


    @Override
    public List<OrgWorkerDO> getOrgWorkerByReportResVo(OrgWorkerPageReqVO pageReqVO){
      return orgWorkerMapper.selectList(pageReqVO);
    }
}