package com.njcn.device.pms.service.majornetwork.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.device.biz.pojo.po.Overlimit;
import com.njcn.device.biz.utils.COverlimitUtil;
import com.njcn.device.pms.enums.PmsDeviceResponseEnum;
import com.njcn.device.pms.mapper.majornetwork.OverlimitMapper;
import com.njcn.device.pms.mapper.majornetwork.PowerDistributionareaMapper;
import com.njcn.device.pms.pojo.param.PowerDistributionareaParam;
import com.njcn.device.pms.pojo.po.PowerDistributionarea;
import com.njcn.device.pms.pojo.po.StatationStat;
import com.njcn.device.pms.pojo.vo.PVCapacity;
import com.njcn.device.pms.service.majornetwork.IDistributionMonitorService;
import com.njcn.device.pms.service.majornetwork.IPowerDistributionareaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.device.pms.service.majornetwork.IStatationStatService;
import com.njcn.event.pojo.vo.DeptLevelVO;
import com.njcn.event.utils.DeptUtil;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.user.pojo.po.Dept;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.BaseParam;
import com.njcn.web.utils.WebUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  台区信息
 * </p>
 *
 * @author hongawen
 * @since 2022-10-14
 */
@Service
@RequiredArgsConstructor
public class PowerDistributionareaServiceImpl extends ServiceImpl<PowerDistributionareaMapper, PowerDistributionarea> implements IPowerDistributionareaService {

    private final DeptFeignClient deptFeignClient;

    private final IStatationStatService iStatationStatService;

    private final IDistributionMonitorService iDistributionMonitorService;


    @Override
    public Page<PowerDistributionarea> getList(BaseParam baseParam) {
        LambdaQueryWrapper<PowerDistributionarea> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PowerDistributionarea::getStatus,DataStateEnum.ENABLE.getCode())
        .and(StrUtil.isNotBlank(baseParam.getSearchValue()),
                i->i.like(PowerDistributionarea::getName,baseParam.getSearchValue())
                .or()
                .like(PowerDistributionarea::getPowerrName,baseParam.getSearchValue())
                .or()
                .like(PowerDistributionarea::getOrgName,baseParam.getSearchValue())).orderByDesc(PowerDistributionarea::getCreateTime);

        //初始化分页数据
        return this.page(new Page<>(PageFactory.getPageNum(baseParam), PageFactory.getPageSize(baseParam)), lambdaQueryWrapper);
    }

    @Override
    public List<PowerDistributionarea> getPowerDistributionList(PowerDistributionareaParam powerDistributionareaParam) {
        LambdaQueryWrapper<PowerDistributionarea> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(StrUtil.isNotBlank(powerDistributionareaParam.getOrgId())){
            List<String> deptIds = deptFeignClient.getDepSonSelfCodetByDeptId(powerDistributionareaParam.getOrgId()).getData();
            lambdaQueryWrapper.in(PowerDistributionarea::getOrgId,deptIds).eq(PowerDistributionarea::getStatus,DataStateEnum.ENABLE.getCode());
        }

        if(StrUtil.isNotBlank(powerDistributionareaParam.getLineId())){
            lambdaQueryWrapper.eq(PowerDistributionarea::getLineId,powerDistributionareaParam.getLineId());
        }
        if(StrUtil.isNotBlank(powerDistributionareaParam.getName())){
            lambdaQueryWrapper.like(PowerDistributionarea::getName,powerDistributionareaParam.getName())
            .or().like(PowerDistributionarea::getOrgName,powerDistributionareaParam.getName());
        }

        lambdaQueryWrapper.select(PowerDistributionarea::getId,PowerDistributionarea::getName,PowerDistributionarea::getOrgId,PowerDistributionarea::getOrgName,PowerDistributionarea::getPowerStationId).last(" limit 1000")
       ;

        lambdaQueryWrapper.orderByDesc(PowerDistributionarea::getCreateTime);
        return this.list(lambdaQueryWrapper);
    }



    /**
     * 根据id查询
     * @author hany
     * @date 2022/10/26
     */
    @Override
    public PowerDistributionarea getDistrictById(String id) {
        return this.getById(id);
    }

    /**
     * 新增台区信息
     * @author hany
     * @date 2022/10/26
     */
    @Override
    public boolean add(PowerDistributionareaParam newParam) {
        LambdaQueryWrapper<PowerDistributionarea> che = new LambdaQueryWrapper<>();
        che.eq(PowerDistributionarea::getId,newParam.getId());
        int count = this.count(che);
        if(count>0){
            throw new BusinessException(PmsDeviceResponseEnum.POWER_CODE_SAME);
        }
        checkName(newParam,true);

        Dept dept = deptFeignClient.getDeptByCode(newParam.getOrgId()).getData();
        if(Objects.isNull(dept)){
            throw new BusinessException(PmsDeviceResponseEnum.ORG_ITEM_EMPTY);
        }

        Dept opDept = deptFeignClient.getDeptByCode(newParam.getOperationId()).getData();
        if(Objects.isNull(opDept)){
            throw new BusinessException(PmsDeviceResponseEnum.Operation_ITEM_EMPTY);
        }

        StatationStat statationStat = iStatationStatService.getStatationStatById(newParam.getPowerStationId());
        if(Objects.isNull(statationStat)){
            throw new BusinessException(PmsDeviceResponseEnum.NO_STATION);
        }


        PowerDistributionarea powerDistributionarea = new PowerDistributionarea();
        BeanUtils.copyProperties(newParam,powerDistributionarea);
        //设为正常状态
        powerDistributionarea.setStatus(DataStateEnum.ENABLE.getCode());
        this.save(powerDistributionarea);

        return true;
    }

    /**
     * 修改台区信息
     * @author hany
     * @date 2022/10/26
     */
    @Override
    public boolean update(PowerDistributionareaParam updateParam) {
        PowerDistributionarea powerDistributionarea = this.getById(updateParam.getId());
        if(Objects.isNull(powerDistributionarea)){
            throw new BusinessException(PmsDeviceResponseEnum.POWER_DIS_NOT_FIND);
        }
        checkName(updateParam,false);
        BeanUtils.copyProperties(updateParam,powerDistributionarea);
        return this.updateById(powerDistributionarea);
    }

    /**
     * 删除
     * @param ids
     */
    @Override
    @Transactional(rollbackFor=RuntimeException.class)
    public boolean delete(List<String> ids) {
        iDistributionMonitorService.removeByIds(ids);
        return this.removeByIds(ids);
    }

    @Override
    public PVCapacity getPVCapacity(StatisticsBizBaseParam param) {
        List<DeptDTO> data = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<String> deptCode = data.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        return this.baseMapper.selectPVCapacity(deptCode);
    }

    @Override
    public PVCapacity.PVCapacityCount getPVPermeability(StatisticsBizBaseParam param) {
        List<DeptDTO> data = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<String> deptCode = data.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        return this.baseMapper.selectPPVPermeability(deptCode);
    }

    @Override
    public List<PVCapacity.Absorptive> getAbsorptiveCapacity(StatisticsBizBaseParam param) {
        List<PVCapacity.Absorptive> info=new ArrayList<>();
        List<DeptDTO> data = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<String> deptCode = data.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        //获取所有的数据信息
        List<PVCapacity.Absorptive> list= this.baseMapper.selectAbsorptiveCapacity(deptCode);
        List<DeptLevelVO> deptLevelVOList = DeptUtil.getDeptLevelVOList(data, param.getId());
        PVCapacity.Absorptive absorptive;
        for (DeptLevelVO deptLevelVO : deptLevelVOList) {
            absorptive=new PVCapacity.Absorptive();
            absorptive.setOrg(deptLevelVO.getName());
            if(CollUtil.isNotEmpty(list)){
                List<String>  subsetDept= deptLevelVO.getDeptList().stream().map(DeptLevelVO::getCode).collect(Collectors.toList());
                List<PVCapacity.Absorptive> collect = list.stream().filter(x -> x.getOrg().equals(deptLevelVO.getCode()) ||
                        subsetDept.contains(x.getOrg())).collect(Collectors.toList());
                absorptive.setCapacity(NumberUtil.round(collect.stream().mapToDouble(PVCapacity.Absorptive::getCapacity).sum(),2).doubleValue());
                absorptive.setConsumption(NumberUtil.round(collect.stream().mapToDouble(PVCapacity.Absorptive::getConsumption).sum(),2).doubleValue());
            }else{
                absorptive.setCapacity(0.0);
                absorptive.setConsumption(0.0);
            }
            info.add(absorptive);
        }
        return info;
    }

    /**
     * 名称重复校验
     */
    private void checkName(PowerDistributionareaParam newParam, boolean flag){
        LambdaQueryWrapper<PowerDistributionarea> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PowerDistributionarea::getName,newParam.getName());
        //修改
        if(!flag){
            lambdaQueryWrapper.ne(PowerDistributionarea::getId,newParam.getId());
        }
        int result = this.count(lambdaQueryWrapper);
        //大于等于1个则表示重复
        if (result >= 1) {
            throw new BusinessException(PmsDeviceResponseEnum.MODEL_NAME_REPEAT);
        }

    }
}
