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

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 org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
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.module.smartfactory.enums.ErrorCodeConstants.FACTORY_INFO_NOT_EXISTS;

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

    @Resource
    private FactoryInfoMapper factoryInfoMapper;

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

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

    @Override
    public void deleteFactoryInfo(Long id) {
        // 校验存在
        validateFactoryInfoExists(id);
        // 删除
        factoryInfoMapper.deleteById(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 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, 1L);
        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);
    }

}