package cn.iocoder.yudao.module.smartfactory.service.factoryinfo;

import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.FactoryInfoPageReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.factoryinfo.vo.FactoryInfoSaveReqVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.screendata.factory.vo.FactoryRollDataRespVO;
import cn.iocoder.yudao.module.smartfactory.controller.admin.screendata.factory.vo.ProvincesDataRespVO;
import cn.iocoder.yudao.module.smartfactory.dal.dataobject.factoryinfo.FactoryInfoDO;
import cn.iocoder.yudao.module.smartfactory.dal.mysql.factoryinfo.FactoryInfoMapper;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
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.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.FACTORY_INFO_NOT_EXISTS;
import static cn.iocoder.yudao.module.smartfactory.enums.ErrorCodeConstants.FACTOYRY_EXISTS_STAFF;

/**
 * 工厂信息 Service 实现类
 *
 * @author 姚君
 */
@Service
@Validated
public class FactoryInfoServiceImpl implements FactoryInfoService {

    @Resource
    private FactoryInfoMapper factoryInfoMapper;

    @Resource
    private DeptApi deptApi;

    @Resource
    private AdminUserApi userApi;

    @Override
    public Long createFactoryInfo(FactoryInfoSaveReqVO createReqVO) {
        // 插入
        FactoryInfoDO factoryInfo = BeanUtils.toBean(createReqVO, FactoryInfoDO.class);
        factoryInfoMapper.insert(factoryInfo);

        //同步插入对应 生产部的下级部门
        DeptRespDTO deptRespDTO = new DeptRespDTO();
        deptRespDTO.setFactoryId(factoryInfo.getId());
        deptRespDTO.setName(createReqVO.getShortName());
        deptRespDTO.setParentId(130L);  //这里设置上级部门为 生产部
        deptRespDTO.setLeaderUserId(createReqVO.getLeaderUserId());
        deptRespDTO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        deptApi.createDept(deptRespDTO);

        // 返回
        return factoryInfo.getId();
    }

    @Override
    public void updateFactoryInfo(FactoryInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateFactoryInfoExists(updateReqVO.getId());
        // 更新
        FactoryInfoDO updateObj = BeanUtils.toBean(updateReqVO, FactoryInfoDO.class);
        factoryInfoMapper.updateById(updateObj);

        //同步更新 部门信息
        DeptRespDTO deptRespDTO = new DeptRespDTO();
        deptRespDTO.setName(updateReqVO.getShortName());
        deptRespDTO.setLeaderUserId(updateReqVO.getLeaderUserId());
        deptRespDTO.setFactoryId(updateReqVO.getId());
        deptApi.updateDept(deptRespDTO);
    }

    @Override
    public void deleteFactoryInfo(Long id) {
        // 校验存在
        validateFactoryInfoExists(id);

        //校验工厂下是否存在 员工
        DeptRespDTO deptRespDTO = deptApi.getDeptByFactoryId(id).getCheckedData();

        List<Long> deptId = new ArrayList<>();
        deptId.add(deptRespDTO.getId());
        List<AdminUserRespDTO> userRespDTOS = userApi.getUserListByDeptIds(deptId).getCheckedData();

        if (userRespDTOS != null && !userRespDTOS.isEmpty()) {
            throw exception(FACTOYRY_EXISTS_STAFF);
        }

        // 删除
        factoryInfoMapper.deleteById(id);

        //同步删除部门
        deptApi.deleteDept(id);
    }

    private void validateFactoryInfoExists(Long id) {
        if (factoryInfoMapper.selectById(id) == null) {
            throw exception(FACTORY_INFO_NOT_EXISTS);
        }
    }

    @Override
    public FactoryInfoDO getFactoryInfo(Long id) {

        return factoryInfoMapper.selectById(id);
    }

    @Override
    public List<FactoryInfoDO> getFactoryList(Collection<Long> ids) {

        return factoryInfoMapper.selectList(FactoryInfoDO::getId, ids);
    }

    @Override
    public List<FactoryInfoDO> getFactoryListByType() {

        return factoryInfoMapper.selectList(FactoryInfoDO::getType, 3);
    }

    @Override
    public PageResult<FactoryInfoDO> getFactoryInfoPage(FactoryInfoPageReqVO pageReqVO) {
        return factoryInfoMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ProvincesDataRespVO> getProvincesData(String code) {
        // -- 获取当前的地区
        Area area = AreaUtils.getArea(Integer.valueOf(code));
        List<ProvincesDataRespVO> vos = new ArrayList<>();
        LambdaQueryWrapperX<FactoryInfoDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<FactoryInfoDO>();
        //去除中鼐总部
        lambdaQueryWrapperX.ne(FactoryInfoDO::getId, 10000078L);
        Integer type = area.getType() - 1;
        if (!type.equals(FactoryInfoDO.ADDRESS_TYPE_NATIONWIDE)) {
            lambdaQueryWrapperX.eq(FactoryInfoDO.ADDRESS_TYPE_PROVINCE.equals(type), FactoryInfoDO::getProvinceId, code)
                    .eq(FactoryInfoDO.ADDRESS_TYPE_CITY.equals(type), FactoryInfoDO::getCityId, code)
                    .eq(FactoryInfoDO.ADDRESS_TYPE_DISTRICT_NAME.equals(type), FactoryInfoDO::getAdCode, code);
        }
        List<FactoryInfoDO> dos = factoryInfoMapper.selectList(
                lambdaQueryWrapperX
        );
        Map<Long, List<FactoryInfoDO>> map = new HashMap<>();
        if (FactoryInfoDO.ADDRESS_TYPE_NATIONWIDE.equals(type)) {
            map = dos.stream().collect(Collectors.groupingBy(FactoryInfoDO::getProvinceId));
        }
        if (FactoryInfoDO.ADDRESS_TYPE_PROVINCE.equals(type)) {
            map = dos.stream().collect(Collectors.groupingBy(FactoryInfoDO::getCityId));
        }
        if (FactoryInfoDO.ADDRESS_TYPE_CITY.equals(type)) {
            map = dos.stream().collect(Collectors.groupingBy(FactoryInfoDO::getAdCode));
        }
        if (FactoryInfoDO.ADDRESS_TYPE_DISTRICT_NAME.equals(type)) {
            map = dos.stream().collect(Collectors.groupingBy(FactoryInfoDO::getId));
        }
        for (Map.Entry<Long, List<FactoryInfoDO>> entry : map.entrySet()) {
            ProvincesDataRespVO vo = new ProvincesDataRespVO();
            vo.setAdCode(entry.getKey());
            vo.setValue(entry.getValue().size());
            vo.setVos(entry.getValue());
            vos.add(vo);
        }
        return vos;
    }

    @Override
    public List<FactoryRollDataRespVO> getFactoryRollData() {
        return factoryInfoMapper.getFactoryRollData();
    }

    @Override
    public List<FactoryInfoDO> list() {
        return factoryInfoMapper.selectList();
    }

    @Override
    public String getWeatherCodeByFactoryId(Long factoryId, String areaCode) {
        return factoryInfoMapper.getWeatherCodeByFactoryId(factoryId, areaCode);
    }
}