package com.huatek.busi.service.impl;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.huatek.busi.common.BusiConstant;
import com.huatek.busi.dto.PushAlarmsDto;
import com.huatek.busi.entity.*;
import com.huatek.busi.service.*;
import com.huatek.busi.service.arrester.BusiArresterSensorService;
import com.huatek.busi.service.gis.BusiGisSensorService;
import com.huatek.busi.service.temperature.BusiTemperPointService;
import com.huatek.busi.service.transformer.BusiTransformerSensorService;
import com.huatek.busi.vo.ResponseVo;
import com.huatek.torch.frame.tools.ConstantUtil;
import com.huatek.torch.frame.tools.ResultUtil;
import com.huatek.torch.util.uuid.Uuid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import com.huatek.busi.common.BusiConstant.DealStatus;
import com.huatek.busi.common.BusiConstant.MalfunctionSource;
import com.huatek.busi.common.BusiConstant.WarningType;
import com.huatek.busi.common.SiteConstants.Status;
import com.huatek.busi.common.util.GenerateUtil;
import com.huatek.busi.dao.BusiEqmWarningDao;
import com.huatek.busi.dto.BusiEqmWarningDto;
import com.huatek.busi.dto.EquipmentInfoDto;
import com.huatek.busi.mapper.BusiEqmWarningMapper;
import com.huatek.busi.vo.BusiEqmMalfunctionVo;
import com.huatek.busi.vo.BusiEqmWarningVo;
import com.huatek.busi.vo.warning.BusiHomePageWarningVo;
import com.huatek.torch.sql.beans.LocalUser;
import com.huatek.torch.util.tools.UserUtil;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;

/**
 * 设备预警表 ServiceImpl
 *
 * @author anker_cheng
 * @date Jun 26, 2019 3:31:54 PM
 */
@Slf4j
@Component
@Service(interfaceClass = BusiEqmWarningService.class)
@Transactional(rollbackFor = Exception.class)
public class BusiEqmWarningServiceImpl implements BusiEqmWarningService {

    @Autowired
    private BusiEqmWarningMapper busiEqmWarningMapper;

    @Autowired
    private BusiEqmWarningDao busiEqmWarningDao;

    @Autowired
    private BusiEqmMalfunctionService busiEqmMalfunctionService;

    @Autowired
    private BusiEqmWarningInfoService busiEqmWarningInfoService;

    @Autowired
    private BusiTemperPointService busiTemperPointService;

    @Autowired
    private BusiArresterSensorService arresterSensorService;

    @Autowired
    private BusiTransformerSensorService transformerSensorService;

    @Autowired
    private BusiGisSensorService busiGisSensorService;

    @Autowired
    private BusiOtherSensorService busiOtherSensorService;

    @Reference(check = false)
    IBusiCableSensorService busiCableSensorService;

    @Override
    public int save(BusiEqmWarning busiEqmWarning) {
        return busiEqmWarningDao.saveOrUpdate(busiEqmWarning);
    }

    @Override
    public BusiEqmWarning saveBusiEqmWarning(EquipmentInfoDto equipmentInfo, String eqType, String gzType, String cacMonitorTypeCode,
                                             LocalDateTime warningTime, String warningMsg, String warningFlag) {
        BusiEqmWarning busiEqmWarning = new BusiEqmWarning();
        busiEqmWarning.setEqType(eqType);
        busiEqmWarning.setWarningFlag(warningFlag);
        busiEqmWarning.setGzType(gzType);
        busiEqmWarning.setWarningMsg(warningMsg);
        busiEqmWarning.setWarningTypeCode(cacMonitorTypeCode);
        busiEqmWarning.setDelFlag(Status.NORMAL.getValue());
        busiEqmWarning.setWarningTime(warningTime);
        if (equipmentInfo != null) {
            busiEqmWarning.setSubTreeId(equipmentInfo.getSubTreeId());
            busiEqmWarning.setSubEquipmentBrand(equipmentInfo.getSubEquipmentBrand());
            busiEqmWarning.setSubEquipmentId(equipmentInfo.getSubEquipmentId());
            busiEqmWarning.setSubEquipmentInstallLocation(equipmentInfo.getSubEquipmentPosition());
            busiEqmWarning.setSubEquipmentManufactor(equipmentInfo.getSubEquipmentManufactor());
            busiEqmWarning.setSubEquipmentName(equipmentInfo.getSubEquipmentName());
            busiEqmWarning.setMainTreeId(equipmentInfo.getMainTreeId());
            busiEqmWarning.setMainEquipmentId(equipmentInfo.getMainEquipmentId());
            busiEqmWarning.setSensorBrand(equipmentInfo.getSensorBrand());
            busiEqmWarning.setSensorId(equipmentInfo.getSensorCode());
            busiEqmWarning.setSensorInstallLocation(equipmentInfo.getSensorPositionDes());
            busiEqmWarning.setSensorManufactor(equipmentInfo.getSensorManufactor());
            busiEqmWarning.setSensorName(equipmentInfo.getSensorName());
            busiEqmWarning.setSiteId(equipmentInfo.getSiteId());

        }
        busiEqmWarning.setDealStatus("0");
        busiEqmWarning.setCreateTime(LocalDateTime.now());
        if (StringUtils.isEmpty(busiEqmWarning.getWarningCode())) {
            busiEqmWarning.setWarningCode(GenerateUtil.generateCode(17));
        }
        busiEqmWarningDao.saveOrUpdate(busiEqmWarning);
        return busiEqmWarning;
    }

    @Override
    public BusiEqmWarning saveBusiEqmCableWarning(EquipmentInfoDto equipmentInfo, String eqType, String gzType, String cacMonitorTypeCode,
                                             LocalDateTime warningTime, String warningMsg,String warningFlag,String runState) {
        BusiEqmWarning busiEqmWarning = new BusiEqmWarning();
        busiEqmWarning.setEqType(eqType);
        busiEqmWarning.setWarningFlag(warningFlag);
        busiEqmWarning.setGzType(gzType);
        busiEqmWarning.setWarningMsg(warningMsg);
        busiEqmWarning.setWarningTypeCode(cacMonitorTypeCode);
        busiEqmWarning.setDelFlag(Status.NORMAL.getValue());
        busiEqmWarning.setWarningTime(warningTime);
        busiEqmWarning.setRunState(runState);
        if (equipmentInfo != null) {
            busiEqmWarning.setSubTreeId(equipmentInfo.getSubTreeId());
            busiEqmWarning.setSubEquipmentBrand(equipmentInfo.getSubEquipmentBrand());
            busiEqmWarning.setSubEquipmentId(equipmentInfo.getSubEquipmentId());
            busiEqmWarning.setSubEquipmentInstallLocation(equipmentInfo.getSubEquipmentPosition());
            busiEqmWarning.setSubEquipmentManufactor(equipmentInfo.getSubEquipmentManufactor());
            busiEqmWarning.setSubEquipmentName(equipmentInfo.getSubEquipmentName());
            busiEqmWarning.setMainTreeId(equipmentInfo.getMainTreeId());
            busiEqmWarning.setMainEquipmentId(equipmentInfo.getMainEquipmentId());
            busiEqmWarning.setSensorBrand(equipmentInfo.getSensorBrand());
            busiEqmWarning.setSensorId(equipmentInfo.getSensorCode());
            busiEqmWarning.setSensorInstallLocation(equipmentInfo.getSensorPositionDes());
            busiEqmWarning.setSensorManufactor(equipmentInfo.getSensorManufactor());
            busiEqmWarning.setSensorName(equipmentInfo.getSensorName());
            busiEqmWarning.setSiteId(equipmentInfo.getSiteId());

        }
        busiEqmWarning.setDealStatus("0");
        busiEqmWarning.setCreateTime(LocalDateTime.now());
        if (StringUtils.isEmpty(busiEqmWarning.getWarningCode())) {
            busiEqmWarning.setWarningCode(GenerateUtil.generateCode(17));
        }
        busiEqmWarningDao.saveOrUpdate(busiEqmWarning);

        return busiEqmWarning;
    }

    @Override
    public int saveBusiEqmWarningInfo(BusiEqmWarning busiEqmWarning, String warningInfo) {
        BusiEqmWarningInfo busiEqmWarningInfo = new BusiEqmWarningInfo();
        busiEqmWarningInfo.setWarningId(busiEqmWarning.getId());
        busiEqmWarningInfo.setWarningInfo(warningInfo);
        return busiEqmWarningInfoService.save(busiEqmWarningInfo);
    }

    @Override
    public PageInfo<BusiEqmWarningVo> findBusiEqmWarningPage(BusiEqmWarningDto busiEqmWarningDto) {
        return PageHelper.startPage(busiEqmWarningDto.getPage(), busiEqmWarningDto.getLimit())
            .doSelectPageInfo(() -> busiEqmWarningMapper.selectBusiEqmWarningPage(busiEqmWarningDto));
    }

    @Override
    public Map<String, Object> dowholeDeal(String token,BusiEqmWarningDto busiEqmWarning) {
        LocalUser user = UserUtil.getLocalUser(token);
        busiEqmWarning.setDealStatus(DealStatus.DEALED);
        busiEqmWarning.setProcessingTime(LocalDateTime.now());
        busiEqmWarning.setWarningType(WarningType.MISREPORT);
        if(user != null) {
            busiEqmWarning.setProcessingUser(user.getUid());
        }
        int count = busiEqmWarningMapper.wholeupdateBusiEqmWarning(busiEqmWarning);
        if (count > 0) {
            log.debug("dowholeDeal: {}", count);
            return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, "处理成功", "");
        }
        return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "处理失败", "");
    }

    @Override
    public Map<String, Object> dosingleDeal(String token,BusiEqmWarningDto busiEqmWarning) {
        LocalUser user = UserUtil.getLocalUser(token);
        busiEqmWarning.setDealStatus(DealStatus.DEALED);
        busiEqmWarning.setProcessingTime(LocalDateTime.now());
        busiEqmWarning.setWarningType(WarningType.MISREPORT);
        if(user != null) {
            busiEqmWarning.setProcessingUser(user.getUid());
        }
        int count = busiEqmWarningMapper.singleupdateBusiEqmWarning(busiEqmWarning);
        if (count > 0) {
            log.debug("dowholeDeal: {}", count);
            return ResultUtil.put(ConstantUtil.REQUEST_SUCCESS, "处理成功", "");
        }
        return ResultUtil.put(ConstantUtil.REQUEST_FAIL, "处理失败", "");
    }

    @Override
	public PageInfo<BusiEqmWarningVo> queryThresholdList(BusiEqmWarningDto busiEqmWarningDto) {
    	 return PageHelper.startPage(busiEqmWarningDto.getPage(), busiEqmWarningDto.getLimit())
    	            .doSelectPageInfo(() -> busiEqmWarningMapper.queryThresholdList(busiEqmWarningDto));
	}

	@Override
    public void     doDeal(String token, List<String> warningIds, String warningType, String dealMsg) {
        if(CollectionUtils.isEmpty(warningIds)) {
            return;
        }
        LocalUser user = UserUtil.getLocalUser(token);
        for(String warningId : warningIds) {
            String dealStatus = busiEqmWarningMapper.lockDealStatus(warningId);
            if(DealStatus.DEALED.equals(dealStatus)) {
                log.warn("已处理：{}", warningId);
//                continue; 目前可以重复处理，该处不校验
            }
            BusiEqmWarning busiEqmWarning = busiEqmWarningDao.get(warningId);
            if(busiEqmWarning == null) {
                log.debug("告警信息不存在！ ID：{}", warningId);
                continue ;
            }
            busiEqmWarning.setWarningType(warningType);
            busiEqmWarning.setDealStatus(DealStatus.DEALED);
            busiEqmWarning.setDealMsg(dealMsg);
            busiEqmWarning.setProcessingTime(LocalDateTime.now());
            if(user != null) {
                busiEqmWarning.setProcessingUser(user.getUid());
            }
            busiEqmWarningDao.updateLocal(busiEqmWarning);
        }
    }

    @Override
    public void toRepair(String token, List<String> warningIds, String dealMsg) {
        if(CollectionUtils.isEmpty(warningIds)) {
            return;
        }
        LocalUser user = UserUtil.getLocalUser(token);
        for(String warningId : warningIds) {
            BusiEqmWarning busiEqmWarning = busiEqmWarningDao.get(warningId);
            if(busiEqmWarning == null) {
                log.debug("告警信息不存在！ ID：{}", warningId);
                continue ;
            }
            //处理告警
            busiEqmWarning.setWarningType(WarningType.FAULT);
            busiEqmWarning.setDealStatus(DealStatus.DEALED);
            busiEqmWarning.setDealMsg(dealMsg);
            busiEqmWarning.setProcessingTime(LocalDateTime.now());
            if(user != null) {
                busiEqmWarning.setProcessingUser(user.getUid());
            }
            busiEqmWarningDao.updateLocal(busiEqmWarning);

            /////转故障
            busiEqmMalfunctionService.warningToMalfunction(token, busiEqmWarning,MalfunctionSource.WARNING);


//            if(EqType.EQ_TYPE1.equals(busiEqmWarning.getEqType())) {
//                busiOfflineTransformerRepairService.toRepair(token, busiEqmWarning);
//            }else if(EqType.EQ_TYPE2.equals(busiEqmWarning.getEqType())) {
//                busiOfflineGisRepairService.toRepair(token, busiEqmWarning);
//            }else if(EqType.EQ_TYPE3.equals(busiEqmWarning.getEqType())) {
//                busiOfflineArresterRepairService.toRepair(token, busiEqmWarning);
//            }else {
//                log.warn("告警转检修单！告警：{}，大类：{}", warningId, busiEqmWarning.getEqType());
//            }
        }
    }

    @Override
    public PageInfo<BusiHomePageWarningVo> findCurrentWarningList(BusiEqmWarningDto dto) {
        //分页查询
        PageInfo<BusiHomePageWarningVo> pageInfo = PageHelper.startPage(dto.getPage(), dto.getLimit())
                .doSelectPageInfo(() -> busiEqmWarningMapper.findCurrentWarningList(dto));
        //不同类型不同次数
        pageInfo.getList().stream().forEach(warning ->{
            setData(warning);
        });
        return pageInfo;
    }

    @Override
    public PageInfo<BusiHomePageWarningVo> findCurrentWarningBySensorCodeList(BusiEqmWarningDto dto) {
        PageInfo<BusiHomePageWarningVo> pageInfo = PageHelper.startPage(dto.getPage(), dto.getLimit())
                .doSelectPageInfo(() -> busiEqmWarningMapper.findCurrentWarningBySensorCodeList(dto));
        //不同类型不同次数
        pageInfo.getList().stream().forEach(warning ->{
            setData(warning);
        });
        return pageInfo;
    }



    private void setData(BusiHomePageWarningVo warning) {
        if(BusiConstant.EqType.EQ_TYPE1.equals(warning.getEqType()))
        {
            if (BusiConstant.GzType.GZ_TYPE9.equals(warning.getGzType())) {
                warning.setWarningCount(busiEqmWarningMapper.getCurrentWarningSum(warning.getSensorCode(), warning.getEqType(), warning.getGzType()));
                return;
            }
            if(!StringUtils.isEmpty(warning.getSensorCode())){
                 BusiTransformerSensor sensorCode = transformerSensorService.findSensorBySensorCode(warning.getSensorCode());
                if(null!=sensorCode){
                    warning.setSensorName(sensorCode.getSensorName());
                    warning.setPosition(sensorCode.getPosition());
                }
            }

        }
        if(BusiConstant.EqType.EQ_TYPE2.equals(warning.getEqType()))
        {   if(!StringUtils.isEmpty(warning.getSensorCode())){
            if(warning.getSensorCode().equals("GISPD")){
                warning.setSensorName("GIS局部放电诊断");
                warning.setPosition("/");
            }else if (warning.getSensorCode().equals("GISmec")){
                warning.setSensorName("GIS机械故障诊断");
                warning.setPosition("/");
            }else if (warning.getSensorCode().equals("assess")){
                warning.setSensorName("断路器状态诊断");
                warning.setPosition("/");
            }else {
                BusiGisSensor sensorCode = busiGisSensorService.findSensorBySensorCode(warning.getSensorCode());
                warning.setSensorName(sensorCode.getSensorName());
                warning.setPosition(sensorCode.getPosition());
            }
            }

        }
        if(BusiConstant.EqType.EQ_TYPE3.equals(warning.getEqType()))
        {
            if(warning.getSensorCode().equals("switch")){
                warning.setSensorName("开关柜机械故障诊断");
                warning.setPosition("/");
            } else {
                BusiArresterSensor sensorCode = arresterSensorService.findSensorBySensorCode(warning.getSensorCode());
                warning.setSensorName(sensorCode.getSensorName());
                warning.setPosition(sensorCode.getPosition());
            }
        }
        if(BusiConstant.EqType.EQ_TYPE4.equals(warning.getEqType()))
        {
            if(!StringUtils.isEmpty(warning.getSensorCode())) {
                BusiTemperPoint sensorCode = busiTemperPointService.findSensorBySensorCode(warning.getSensorCode());
                warning.setSensorName(sensorCode.getSensorName());
                warning.setPosition(sensorCode.getPosition());
            }
        }
        if(BusiConstant.EqType.EQ_TYPE5.equals(warning.getEqType()))
        {
            if(!StringUtils.isEmpty(warning.getSensorCode())) {
                BusiOtherSensor sensorCode = busiOtherSensorService.findSensorBySensorCode(warning.getSensorCode());
                warning.setSensorName(sensorCode.getSensorName());
                warning.setPosition(sensorCode.getPosition());
            }
        }
        if(Objects.equals(BusiConstant.EqType.EQ_TYPE6, warning.getEqType())){
            if(warning.getSensorCode().equals("Generator")){
                warning.setSensorName("发电机定子绝缘状态");
                warning.setPosition("/");
            } else {
//                BusiGeneratorSensor busiGeneratorSensor = busiGeneratorSensorService.findSensorBySensorCode(warning.getSensorCode());
//                warning.setSensorName(busiGeneratorSensor.getSensorName());
//                warning.setPosition(busiGeneratorSensor.getPosition());
            }
        }
        if(Objects.equals(BusiConstant.EqType.EQ_TYPE7, warning.getEqType())){
            if(warning.getSensorCode().equals("Cable")){
                warning.setSensorName("电缆故障诊断");
                warning.setPosition("/");
            } else {
                BusiCableSensor busiCableSensor = busiCableSensorService.findSensorBySensorCode(warning.getSensorCode());
                warning.setSensorName(busiCableSensor.getSensorName());
                warning.setPosition(busiCableSensor.getPosition());
            }
        }
        warning.setWarningCount(busiEqmWarningMapper.getCurrentWarningSum(warning.getSensorCode(), warning.getEqType(), warning.getGzType()));
    }

    @Override
    public String getFalseAlarmRateBySensor(String sensorCode, LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        param.put("sensorCode", sensorCode);
        return getFalseAlarmRate(param);
    }

    @Override
    public String getFalseAlarmRateByMainTreeId(String mainTreeId, LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> param = Maps.newHashMap();
        param.put("mainTreeId", mainTreeId);
        param.put("startTime", startTime);
        param.put("endTime", endTime);
        return getFalseAlarmRate(param);
    }

    @Override
    public Integer getBusiEqmWarningCount(Map<String, Object> param) {
        Integer count = busiEqmWarningMapper.getBusiEqmWarningCount(param);
        return count == null ? 0 : count;
    }

    private String getFalseAlarmRate(Map<String, Object> param) {
        Integer totalCount = this.getBusiEqmWarningCount(param);
        if (totalCount.intValue() == 0) {
            return "0";
        }
        param.put("warningType", WarningType.MISREPORT);
        Integer wbCount = this.getBusiEqmWarningCount(param);
        if (wbCount.intValue() == 0) {
            return "0";
        }
        // 转换成百分比
        DecimalFormat df = new DecimalFormat("0.00");// 设置保留位数
        return df.format((float)wbCount * 100 / totalCount);
    }

    @Override
    public List<BusiEqmWarning> isFinishedEqmMalfunction(List<String> warningIds) {
        List<BusiEqmWarning> list = new ArrayList<BusiEqmWarning>();
        if(CollectionUtils.isEmpty(warningIds)) {
            return list;
        }
        else
        {
            for(String warningId : warningIds) {
                //根据告警id查询未处理的故障单
                BusiEqmMalfunctionVo busiEqmMalfunctionVo = busiEqmMalfunctionService.queryUnprocessedEqmMalfunction(warningId);

                if(busiEqmMalfunctionVo != null)
                {
                    list.add(busiEqmWarningDao.get(warningId));
                }
            }
        }
        return list;
    }

    @Override
    public BusiEqmWarningVo findBusiEqmWarningById(String id) {
        return busiEqmWarningMapper.findBusiEqmWarningById(id);
    }

    @Override
    public List<BusiEqmWarningVo> findBusiEqmWarningList(BusiEqmWarningDto busiEqmWarningDto) {
        return busiEqmWarningMapper.findBusiEqmWarningList(busiEqmWarningDto);
    }

    @Override
    public boolean testWarringAdd(BusiEqmWarningDto busiEqmWarningDto) {
        BusiEqmWarning busiEqmWarning = new BusiEqmWarning();
        BeanUtils.copyProperties(busiEqmWarningDto,busiEqmWarning);
        int add = busiEqmWarningDao.saveOrUpdate(busiEqmWarning);
        return add>0;
    }



    @Override
    public boolean warringEvaluating(String eqType,String gzType,String warningMsg,String mainTreeId,String sensorName) {
        BusiEqmWarning busiEqmWarning = new BusiEqmWarning();
        busiEqmWarning.setEqType(eqType);
        busiEqmWarning.setGzType(gzType);
        busiEqmWarning.setDelFlag("1");
        busiEqmWarning.setDealStatus("0");
        busiEqmWarning.setWarningMsg(warningMsg);
        busiEqmWarning.setWarningTime( LocalDateTime.now());
        busiEqmWarning.setCreateTime(LocalDateTime.now());
        busiEqmWarning.setMainTreeId(mainTreeId);
        busiEqmWarning.setSensorName(sensorName);
        int add = busiEqmWarningDao.saveOrUpdate(busiEqmWarning);
        return add>0;
    }
}
