/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.modular.env.envdevice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.common.pojo.CommonResult;
import vip.xiaonuo.core.enums.EnvDataTypeEnum;
import vip.xiaonuo.modular.base.baseConfig.entity.BaseConfig;
import vip.xiaonuo.modular.base.baseConfig.mapper.BaseConfigMapper;
import vip.xiaonuo.modular.base.pigpen.entity.BasePigpen;
import vip.xiaonuo.modular.base.pigpen.mapper.BasePigpenMapper;
import vip.xiaonuo.modular.energy.energyDevice.entity.EnergyDevice;
import vip.xiaonuo.modular.env.entity.EnvDeviceEquipment;
import vip.xiaonuo.modular.env.envdevice.entity.EnvDevice;
import vip.xiaonuo.modular.env.envdevice.entity.vo.EnvDeviceCountVo;
import vip.xiaonuo.modular.env.envdevice.mapper.EnvDeviceMapper;
import vip.xiaonuo.modular.env.envdevice.param.*;
import vip.xiaonuo.modular.env.envdevice.service.EnvDeviceService;
import vip.xiaonuo.modular.env.mapper.EnvDeviceEquipmentMapper;

import javax.validation.constraints.NotBlank;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 环控设备Service接口实现类
 *
 * @author newspaper
 * @date  2023/12/18 09:58
 **/
@Service
public class EnvDeviceServiceImpl extends ServiceImpl<EnvDeviceMapper, EnvDevice> implements EnvDeviceService {

    @Autowired
    private EnvDeviceMapper envDeviceMapper;
    @Autowired
    private EnvDeviceEquipmentMapper equipmentMapper;
    @Autowired
    private BaseConfigMapper baseConfigMapper;
    @Autowired
    private BasePigpenMapper basePigpenMapper;

    @Override
    public Page<EnvDevice> page(EnvDevicePageParam envDevicePageParam) {
        String orgId = envDevicePageParam.getOrgId();
        QueryWrapper<EnvDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id",orgId).orderByAsc("id");
        if(ObjectUtil.isNotEmpty(envDevicePageParam.getDeviceType())) {
            queryWrapper.eq("device_type", envDevicePageParam.getDeviceType());
        }
        String installPosition = envDevicePageParam.getInstallPosition();
        List<String> pigpenList = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(installPosition)) {
            BasePigpen basePigpen = basePigpenMapper.selectById(installPosition);
            Integer type = basePigpen.getType();
            switch (type) {
                case 0:
                    List<BasePigpen> basePigpens = basePigpenMapper.selectList(new QueryWrapper<BasePigpen>().lambda().eq(BasePigpen::getParentId, basePigpen.getId()));
                    if (ObjectUtil.isNotEmpty(basePigpens)) {
                        pigpenList.addAll(basePigpens.stream().map(basePigpen1 -> basePigpen1.getId()).collect(Collectors.toList()));
                    }
                    for (BasePigpen pigpen : basePigpens) {
                        List<BasePigpen> childPigpens = basePigpenMapper.selectList(new QueryWrapper<BasePigpen>().lambda().eq(BasePigpen::getParentId, pigpen.getId()));
                        if (ObjectUtil.isNotEmpty(childPigpens)) {
                            pigpenList.addAll(childPigpens.stream().map(basePigpen2 -> basePigpen2.getId()).collect(Collectors.toList()));
                        }
                    }
                    break;
                case 1:
                    List<BasePigpen> pigpens = basePigpenMapper.selectList(new QueryWrapper<BasePigpen>().lambda().eq(BasePigpen::getParentId, basePigpen.getId()));
                    if (ObjectUtil.isNotEmpty(pigpens)) {
                        pigpenList.addAll(pigpens.stream().map(basePigpen3 -> basePigpen3.getId()).collect(Collectors.toList()));
                    }
                case 2:
                    pigpenList.add(installPosition);
                    break;
            }
            queryWrapper.lambda().in(EnvDevice::getInstallPosition, pigpenList);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);


    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommonResult add(EnvDeviceAddParam envDeviceAddParam) {
        EnvDevice envDevice = BeanUtil.toBean(envDeviceAddParam, EnvDevice.class);
        QueryWrapper<EnvDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_id", envDeviceAddParam.getOrgId())
                .eq("device_code", envDeviceAddParam.getDeviceCode())
                .or().eq("install_position", envDeviceAddParam.getInstallPosition());
        if (ObjectUtil.isEmpty(envDeviceMapper.selectOne(queryWrapper))) {
            for (int i = 1; i <= envDeviceAddParam.getFanNum(); i++) {
                EnvDeviceEquipment equipment = new EnvDeviceEquipment();
                equipment.setDeviceCode(envDeviceAddParam.getDeviceCode());
                if (i < 10){
                    equipment.setChipCode(envDeviceAddParam.getDeviceCode() + "010"+i);
                }else {
                    equipment.setChipCode(envDeviceAddParam.getDeviceCode() + "01"+i);
                }
                equipment.setCreateTime(new Date());
                equipment.setOrgId(envDeviceAddParam.getOrgId());
                equipment.setDeviceType(0);
                equipmentMapper.insert(equipment);
            }
            for (int i = 1; i <= envDeviceAddParam.getCurtainNum(); i++) {
                EnvDeviceEquipment equipment = new EnvDeviceEquipment();
                equipment.setDeviceCode(envDeviceAddParam.getDeviceCode());
                if (i < 10){
                    equipment.setChipCode(envDeviceAddParam.getDeviceCode() + "020"+i);
                }else {
                    equipment.setChipCode(envDeviceAddParam.getDeviceCode() + "02"+i);
                }
                equipment.setCreateTime(new Date());
                equipment.setOrgId(envDeviceAddParam.getOrgId());
                equipment.setDeviceType(1);
                equipmentMapper.insert(equipment);
            }
            this.save(envDevice);
            return CommonResult.ok();
        } else {
            return new CommonResult(500, "设备编号重复或者安装位置已存在设备", false);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(EnvDeviceEditParam envDeviceEditParam) {
        EnvDevice envDevice = this.queryEntity(envDeviceEditParam.getId());
        String orgId = envDevice.getOrgId();
        BeanUtil.copyProperties(envDeviceEditParam, envDevice);
        if (this.count(new QueryWrapper<EnvDevice>().lambda()
                .eq(EnvDevice::getOrgId,orgId)
                .eq(EnvDevice::getDeviceCode,envDevice.getDeviceCode())
                .ne(EnvDevice::getId,envDevice.getId())) > 0) {
            throw new CommonException("存在相同设备编号,编号为:{}",envDevice.getDeviceCode());
        }
        if (this.count(new QueryWrapper<EnvDevice>().lambda()
                .eq(EnvDevice::getOrgId,orgId)
                .eq(EnvDevice::getDeviceName,envDevice.getDeviceName())
                .ne(EnvDevice::getId,envDevice.getId())) > 0) {
            throw new CommonException("存在相同设备名称,名称为:{}",envDevice.getDeviceName());
        }
        if (this.count(new QueryWrapper<EnvDevice>().lambda()
                .eq(EnvDevice::getOrgId,orgId)
                .eq(EnvDevice::getInstallPosition,envDevice.getInstallPosition())
                .ne(EnvDevice::getId,envDevice.getId())) > 0) {
            throw new CommonException("该位置已存在设备!");
        }
        equipmentMapper.delete(new QueryWrapper<EnvDeviceEquipment>().lambda()
                .eq(EnvDeviceEquipment::getDeviceCode,envDeviceEditParam.getDeviceCode())
                .eq(EnvDeviceEquipment::getOrgId,envDeviceEditParam.getOrgId()));
        for (int i = 1; i <= envDeviceEditParam.getFanNum(); i++) {
            EnvDeviceEquipment equipment = new EnvDeviceEquipment();
            equipment.setDeviceCode(envDeviceEditParam.getDeviceCode());
            if (i < 10){
                equipment.setChipCode(envDeviceEditParam.getDeviceCode() + "010"+i);
            }else {
                equipment.setChipCode(envDeviceEditParam.getDeviceCode() + "01"+i);
            }
            equipment.setCreateTime(new Date());
            equipment.setOrgId(envDeviceEditParam.getOrgId());
            equipment.setDeviceType(0);
            equipmentMapper.insert(equipment);
        }
        for (int i = 1; i <= envDeviceEditParam.getCurtainNum(); i++) {
            EnvDeviceEquipment equipment = new EnvDeviceEquipment();
            equipment.setDeviceCode(envDeviceEditParam.getDeviceCode());
            if (i < 10){
                equipment.setChipCode(envDeviceEditParam.getDeviceCode() + "020"+i);
            }else {
                equipment.setChipCode(envDeviceEditParam.getDeviceCode() + "02"+i);
            }
            equipment.setCreateTime(new Date());
            equipment.setOrgId(envDeviceEditParam.getOrgId());
            equipment.setDeviceType(1);
            equipmentMapper.insert(equipment);
        }
        this.updateById(envDevice);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<EnvDeviceIdParam> envDeviceIdParamList) {
        List<String> toDeleteDeviceIdList = CollStreamUtil.toList(envDeviceIdParamList, EnvDeviceIdParam::getId);
        // 执行删除
        this.removeByIds(toDeleteDeviceIdList);
    }

    @Override
    public EnvDevice detail(EnvDeviceIdParam envDeviceIdParam) {
        return envDeviceMapper.detail(envDeviceIdParam.getId());
    }

    @Override
    public EnvDevice queryEntity(String id) {
        EnvDevice envDevice = this.getById(id);
        if(ObjectUtil.isEmpty(envDevice)) {
            throw new CommonException("环控设备不存在，id值为：{}", id);
        }
        return envDevice;
    }

    @Override
    public EnvDeviceCountVo deviceCount(EnvDeviceOrgIdParam envDeviceOrgIdParam) {
        EnvDeviceCountVo envDeviceCountVo = new EnvDeviceCountVo();
        String orgId = envDeviceOrgIdParam.getOrgId();
        long deviceNum = this.count(new QueryWrapper<EnvDevice>().lambda().eq(EnvDevice::getOrgId, orgId));
        if (deviceNum == 0){
            envDeviceCountVo.setDeviceNum(0L);
            envDeviceCountVo.setOnDeviceNum(0L);
            envDeviceCountVo.setOffDeviceNum(0L);
            envDeviceCountVo.setOnlineRate("0%");
        }else {
            envDeviceCountVo.setDeviceNum(deviceNum);
            long onDeviceNum = this.count(new QueryWrapper<EnvDevice>().lambda().eq(EnvDevice::getStatus,"1").eq(EnvDevice::getOrgId, orgId));
            envDeviceCountVo.setOnDeviceNum(onDeviceNum);
            long offDeviceNum = this.count(new QueryWrapper<EnvDevice>().lambda().eq(EnvDevice::getStatus,"0").eq(EnvDevice::getOrgId, orgId));
            envDeviceCountVo.setOffDeviceNum(offDeviceNum);
            //创建一个数值格式化对象
            NumberFormat numberFormat = NumberFormat.getInstance();
            //设置精确到小数点后两位
            numberFormat.setMaximumFractionDigits(2);
            String onlineRate = numberFormat.format((float)onDeviceNum / (float) deviceNum* 100) + "%";
            envDeviceCountVo.setOnlineRate(onlineRate);
        }
        return envDeviceCountVo;
    }

    @Override
    public List<BaseConfig> deviceTypeSelector(EnvDeviceOrgIdParam envDeviceOrgIdParam) {
        String orgId = envDeviceOrgIdParam.getOrgId();
        String parentId = baseConfigMapper.selectOne(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getParentId, 0).eq(BaseConfig::getConfigName, "环控设备类型")).getId();
        List<BaseConfig> baseConfigs = baseConfigMapper.selectList(new QueryWrapper<BaseConfig>().lambda().eq(BaseConfig::getParentId, parentId).eq(BaseConfig::getOrgId, orgId));
        return baseConfigs;
    }

    @Override
    public List<EnvDeviceEquipment> getEquipmentByUnitId(unitIdParam unitIdParam) {
        EnvDevice envDevice = this.getOne(new QueryWrapper<EnvDevice>().lambda().eq(EnvDevice::getInstallPosition, unitIdParam.getUnitId()));

        return null;
    }
}
