package com.usky.fire.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.util.BeanMapperUtils;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.fire.domain.*;
import com.usky.fire.mapper.AlarmElectricalFireMapper;
import com.usky.fire.service.*;
import com.usky.fire.service.util.OnlineMethod;
import com.usky.fire.service.vo.AlarmFireStatisticalVo;
import com.usky.fire.service.vo.AlarmHiddenDangerVo;
import com.usky.fire.service.vo.DataCountVo;
import com.usky.fire.service.vo.DataVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 电气火灾隐患告警 服务实现类
 * </p>
 *
 * @author JCB
 * @since 2022-08-18
 */
@Service
public class AlarmElectricalFireServiceImpl extends AbstractCrudService<AlarmElectricalFireMapper, AlarmElectricalFire> implements AlarmElectricalFireService {

    @Autowired
    private BaseUserCompanyService baseUserCompanyService;

    @Autowired
    private AlarmHydrantWaterService alarmHydrantWaterService;

    @Autowired
    private AlarmSmokeControlService alarmSmokeControlService;

    @Autowired
    private AlarmSprayWaterService alarmSprayWaterService;

    @Autowired
    private AlarmVideoService alarmVideoService;

    @Override
    public CommonPage<AlarmElectricalFire> alarmElectricalFireList(String companyName, Integer handlingStatus, String startDate, String endDate,
                                                                   Integer pageNum, Integer pageSize) {
        IPage<AlarmElectricalFire> page = new Page<>(pageNum, pageSize);
        List<AlarmElectricalFire> list = new ArrayList<>();
        LambdaQueryWrapper<BaseUserCompany> QueryWrapper = Wrappers.lambdaQuery();
        QueryWrapper.select(BaseUserCompany::getCompanyId)
                .eq(BaseUserCompany::getUserId, SecurityUtils.getUserId());
        List<BaseUserCompany> comoanyList = baseUserCompanyService.list(QueryWrapper);
        if (CollectionUtils.isNotEmpty(comoanyList)) {
            List<String> companyIdList = new ArrayList<>();
            for (int i = 0; i < comoanyList.size(); i++) {
                companyIdList.add(comoanyList.get(i).getCompanyId());
            }
            LambdaQueryWrapper<AlarmElectricalFire> queryWrapperOne = Wrappers.lambdaQuery();
            queryWrapperOne.select(AlarmElectricalFire::getId, AlarmElectricalFire::getDeviceCode,
                    AlarmElectricalFire::getDeviceName, AlarmElectricalFire::getAlarmType, AlarmElectricalFire::getAlarmTime,
                    AlarmElectricalFire::getCompanyId, AlarmElectricalFire::getCompanyName, AlarmElectricalFire::getHandlingStatus,
                    AlarmElectricalFire::getHandler, AlarmElectricalFire::getHandlingTime, AlarmElectricalFire::getHandlingContent,
                    AlarmElectricalFire::getFalseAlarm, AlarmElectricalFire::getSitePhoto, AlarmElectricalFire::getAttributeValue4,
                    AlarmElectricalFire::getSystemType)
                    .in(AlarmElectricalFire::getCompanyId, companyIdList)
                    .like(StringUtils.isNotBlank(companyName), AlarmElectricalFire::getCompanyName, companyName)
                    .eq(handlingStatus != null, AlarmElectricalFire::getHandlingStatus, handlingStatus)
                    .between(StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate), AlarmElectricalFire::getAlarmTime, startDate, endDate);
            queryWrapperOne.orderByDesc(AlarmElectricalFire::getId);
            page = this.page(page, queryWrapperOne);
            list = page.getRecords();
            if (CollectionUtils.isNotEmpty(list)) {
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setAlarmTypeName(OnlineMethod.alarmName(list.get(i).getAlarmType()));
                    list.get(i).setReportContent(list.get(i).getDeviceName() + "," + OnlineMethod.alarmName(list.get(i).getAlarmType()) + ",高警值：" + list.get(i).getAttributeValue4() + "" + OnlineMethod.company(list.get(i).getAlarmType()));
                }
            }
        }
        return new CommonPage<>(list, page.getTotal(), pageSize, pageNum);
    }

    public CommonPage<AlarmHiddenDangerVo> alarmHiddenDangerList(Integer systemType, String companyName, Integer handlingStatus, String startDate, String endDate,
                                                                 Integer pageNum, Integer pageSize) {
        CommonPage<AlarmHiddenDangerVo> list = new CommonPage<>();
        list.setCurrent(pageNum);
        list.setSize(pageSize);
        switch (systemType) {
            case 2:
                CommonPage<AlarmSprayWater> list2 = alarmSprayWaterService.alarmSprayWaterList(companyName, handlingStatus, startDate, endDate, pageNum, pageSize);
                list.setRecords(BeanMapperUtils.mapList(list2.getRecords(), AlarmSprayWater.class, AlarmHiddenDangerVo.class));
                list.setTotal(list2.getTotal());
                break;
            case 3:
                CommonPage<AlarmHydrantWater> list3 = alarmHydrantWaterService.alarmHydrantWaterList(companyName, handlingStatus, startDate, endDate, pageNum, pageSize);
                list.setRecords(BeanMapperUtils.mapList(list3.getRecords(), AlarmHydrantWater.class, AlarmHiddenDangerVo.class));
                list.setTotal(list3.getTotal());
                break;
            case 4:
                CommonPage<AlarmSmokeControl> list4 = alarmSmokeControlService.alarmSmokeList(companyName, handlingStatus, startDate, endDate, pageNum, pageSize);
                list.setRecords(BeanMapperUtils.mapList(list4.getRecords(), AlarmSmokeControl.class, AlarmHiddenDangerVo.class));
                list.setTotal(list4.getTotal());
                break;
            case 5:
                CommonPage<AlarmElectricalFire> list5 = this.alarmElectricalFireList(companyName, handlingStatus, startDate, endDate, pageNum, pageSize);
                list.setRecords(BeanMapperUtils.mapList(list5.getRecords(), AlarmElectricalFire.class, AlarmHiddenDangerVo.class));
                list.setTotal(list5.getTotal());
                break;
            case 6:
                CommonPage<AlarmVideo> list6 = alarmVideoService.alarmVideoList(companyName, handlingStatus, startDate, endDate, pageNum, pageSize);
                list.setRecords(BeanMapperUtils.mapList(list6.getRecords(), AlarmVideo.class, AlarmHiddenDangerVo.class));
                list.setTotal(list6.getTotal());
                break;
        }
        return list;
    }

    @Override
    public Integer electricalFireCount(List<String> companyIdList, Integer handlingStatus, String companyName, String startDate, String endDate) {
        LambdaQueryWrapper<AlarmElectricalFire> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(CollectionUtils.isNotEmpty(companyIdList), AlarmElectricalFire::getCompanyId, companyIdList)
                .between(StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate), AlarmElectricalFire::getAlarmTime, startDate, endDate)
                .like(StringUtils.isNotBlank(companyName), AlarmElectricalFire::getCompanyName, companyName)
                .eq(handlingStatus != null, AlarmElectricalFire::getHandlingStatus, handlingStatus);
        int total = this.count(queryWrapper);
        return total;
    }


    @Override
    public Map<String, Object> hiddenDangerStatistics(Integer systemType, String companyName, String startDate, String endDate) {
        LambdaQueryWrapper<BaseUserCompany> QueryWrapper = Wrappers.lambdaQuery();
        QueryWrapper.select(BaseUserCompany::getCompanyId)
                .eq(BaseUserCompany::getUserId, SecurityUtils.getUserId());
        List<BaseUserCompany> comoanyList = baseUserCompanyService.list(QueryWrapper);
        int untreated = 0;
        int processed = 0;
        Integer count = 0;
        String disposalRate = "0.00%";
        if (CollectionUtils.isNotEmpty(comoanyList)) {
            List<String> companyIdList = new ArrayList<>();
            for (int i = 0; i < comoanyList.size(); i++) {
                companyIdList.add(comoanyList.get(i).getCompanyId());
            }
            switch (systemType) {
                case 2:
                    untreated = alarmSprayWaterService.sprayWaterCount(companyIdList, 0, companyName, startDate, endDate);
                    processed = alarmSprayWaterService.sprayWaterCount(companyIdList, 1, companyName, startDate, endDate);
                    break;
                case 3:
                    untreated = alarmHydrantWaterService.hydrantWaterCount(companyIdList, 0, companyName, startDate, endDate);
                    processed = alarmHydrantWaterService.hydrantWaterCount(companyIdList, 1, companyName, startDate, endDate);
                    break;
                case 4:
                    untreated = alarmSmokeControlService.smokeCount(companyIdList, 0, companyName, startDate, endDate);
                    processed = alarmSmokeControlService.smokeCount(companyIdList, 1, companyName, startDate, endDate);
                    break;
                case 5:
                    untreated = this.electricalFireCount(companyIdList, 0, companyName, startDate, endDate);
                    processed = this.electricalFireCount(companyIdList, 1, companyName, startDate, endDate);
                    break;
                case 6:
                    untreated = alarmVideoService.videoCount(companyIdList, 0, companyName, startDate, endDate);
                    processed = alarmVideoService.videoCount(companyIdList, 1, companyName, startDate, endDate);
                    break;
            }
            count = untreated + processed;
            disposalRate = OnlineMethod.myPercent(processed, count);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("untreated", untreated);//告警未处理数
        map.put("processed", processed);//告警未处理数
        map.put("disposalRate", disposalRate);//告警处理率
        map.put("alarmCount", count);//告警总数
        return map;
    }


    @Override
    public Map<String, Object> hiddenDangerStatisticalChart(Integer systemType, String startDate, String endDate) {
        LambdaQueryWrapper<BaseUserCompany> QueryWrapper = Wrappers.lambdaQuery();
        QueryWrapper.select(BaseUserCompany::getCompanyId)
                .eq(BaseUserCompany::getUserId, SecurityUtils.getUserId());
        List<BaseUserCompany> comoanyList = baseUserCompanyService.list(QueryWrapper);
        List<Integer> alarmCountList = new ArrayList<>();
        List<Integer> handleCountList = new ArrayList<>();
        List<String> alarmTimeList = new ArrayList<>();
        List<String> handleRateList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(comoanyList)) {
            List<String> companyIdList = new ArrayList<>();
            for (int i = 0; i < comoanyList.size(); i++) {
                companyIdList.add(comoanyList.get(i).getCompanyId());
            }
            String table = "";
            switch (systemType) {
                case 2:
                    table = "alarm_spray_water";
                    break;
                case 3:
                    table = "alarm_hydrant_water";
                    break;
                case 4:
                    table = "alarm_smoke_control";
                    break;
                case 5:
                    table = "alarm_electrical_fire";
                    break;
                case 6:
                    table = "alarm_video";
                    break;
            }
            List<AlarmFireStatisticalVo> list = baseMapper.selectElectricalFireStatistical(table, companyIdList, startDate, endDate);
            for (int i = 0; i < list.size(); i++) {
                alarmCountList.add(list.get(i).getCount());
                handleCountList.add(list.get(i).getSum());
                alarmTimeList.add(list.get(i).getAlarmTime());
                handleRateList.add(OnlineMethod.myPercent(list.get(i).getSum(), list.get(i).getCount()));
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("alarmCountList", alarmCountList);
        map.put("handleCountList", handleCountList);
        map.put("alarmTimeList", alarmTimeList);
        map.put("handleRateList", handleRateList);
        return map;
    }


    @Override
    public void updateAlarmElectricalFire(AlarmElectricalFire alarmElectricalFire) {
        if (alarmElectricalFire.getId() == 0) {
            LambdaQueryWrapper<AlarmElectricalFire> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(AlarmElectricalFire::getAlarmType, alarmElectricalFire.getAlarmType())
                    .eq(AlarmElectricalFire::getDeviceCode, alarmElectricalFire.getDeviceCode());
            List<AlarmElectricalFire> list = this.list(queryWrapper);
            if (CollectionUtils.isNotEmpty(list)) {
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setHandler(SecurityUtils.getUsername());
                    list.get(i).setHandlingTime(LocalDateTime.now());
                    list.get(i).setHandlingStatus(1);
                    list.get(i).setHandlingContent(alarmElectricalFire.getHandlingContent());
                    list.get(i).setHandlerPhone(SecurityUtils.getLoginUser().getSysPerson().getLinkPhone());
                    list.get(i).setFalseAlarm(alarmElectricalFire.getFalseAlarm());
                    this.updateById(list.get(i));
                }
            }
        } else {
            alarmElectricalFire.setHandler(SecurityUtils.getUsername());
            alarmElectricalFire.setHandlingTime(LocalDateTime.now());
            alarmElectricalFire.setHandlingStatus(1);
            alarmElectricalFire.setHandlerPhone(SecurityUtils.getLoginUser().getSysPerson().getLinkPhone());
            this.updateById(alarmElectricalFire);
        }
    }


    @Override
    public void updateHiddenDanger(AlarmHiddenDangerVo alarmHiddenDangerVo) {
        switch (alarmHiddenDangerVo.getSystemType()) {
            case 2:
                AlarmSprayWater alarmSprayWater = BeanMapperUtils.map(alarmHiddenDangerVo, AlarmSprayWater.class);
                alarmSprayWaterService.updateAlarmSmokeControl(alarmSprayWater);
                break;
            case 3:
                AlarmHydrantWater alarmHydrantWater = BeanMapperUtils.map(alarmHiddenDangerVo, AlarmHydrantWater.class);
                alarmHydrantWaterService.updateAlarmHydrantWater(alarmHydrantWater);
                break;
            case 4:
                AlarmSmokeControl alarmSmokeControl = BeanMapperUtils.map(alarmHiddenDangerVo, AlarmSmokeControl.class);
                alarmSmokeControlService.updateAlarmSmokeControl(alarmSmokeControl);
                break;
            case 5:
                AlarmElectricalFire alarmElectricalFire = BeanMapperUtils.map(alarmHiddenDangerVo, AlarmElectricalFire.class);
                this.updateAlarmElectricalFire(alarmElectricalFire);
                break;
            case 6:
                AlarmVideo alarmVideo = BeanMapperUtils.map(alarmHiddenDangerVo, AlarmVideo.class);
                alarmVideoService.updateAlarmVideo(alarmVideo);
                break;
        }
    }

    @Override
    public List<AlarmElectricalFire> alarmElectricalFireListOne(String companyName, Integer handlingStatus, String startDate, String endDate) {
        List<AlarmElectricalFire> list = new ArrayList<>();
        LambdaQueryWrapper<BaseUserCompany> QueryWrapper = Wrappers.lambdaQuery();
        QueryWrapper.select(BaseUserCompany::getCompanyId)
                .eq(BaseUserCompany::getUserId, SecurityUtils.getUserId());
        List<BaseUserCompany> comoanyList = baseUserCompanyService.list(QueryWrapper);
        if (CollectionUtils.isNotEmpty(comoanyList)) {
            List<String> companyIdList = new ArrayList<>();
            for (int i = 0; i < comoanyList.size(); i++) {
                companyIdList.add(comoanyList.get(i).getCompanyId());
            }
            LambdaQueryWrapper<AlarmElectricalFire> queryWrapperOne = Wrappers.lambdaQuery();
            queryWrapperOne.select(AlarmElectricalFire::getId, AlarmElectricalFire::getDeviceCode,
                    AlarmElectricalFire::getDeviceName, AlarmElectricalFire::getAlarmType, AlarmElectricalFire::getAlarmTime,
                    AlarmElectricalFire::getCompanyId, AlarmElectricalFire::getCompanyName, AlarmElectricalFire::getHandlingStatus,
                    AlarmElectricalFire::getHandler, AlarmElectricalFire::getHandlingTime, AlarmElectricalFire::getHandlingContent,
                    AlarmElectricalFire::getFalseAlarm, AlarmElectricalFire::getSitePhoto, AlarmElectricalFire::getAttributeValue4)
                    .in(AlarmElectricalFire::getCompanyId, companyIdList)
                    .like(StringUtils.isNotBlank(companyName), AlarmElectricalFire::getCompanyName, companyName)
                    .eq(handlingStatus != null, AlarmElectricalFire::getHandlingStatus, handlingStatus)
                    .between(StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate), AlarmElectricalFire::getAlarmTime, startDate, endDate);
            queryWrapperOne.orderByDesc(AlarmElectricalFire::getId);
            list = this.list(queryWrapperOne);
            if (CollectionUtils.isNotEmpty(list)) {
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setAlarmTypeName(OnlineMethod.alarmName(list.get(i).getAlarmType()));
                    list.get(i).setReportContent(list.get(i).getDeviceName() + "," + OnlineMethod.alarmName(list.get(i).getAlarmType()) + ",高警值：" + list.get(i).getAttributeValue4() + "" + OnlineMethod.company(list.get(i).getAlarmType()));
                }
            }
        }
        return list;
    }


    @Override
    public List<AlarmHiddenDangerVo> alarmHiddenDangerListOne(Integer systemType, String companyName, Integer handlingStatus, String startDate, String endDate) {
        List<AlarmHiddenDangerVo> list = new ArrayList<>();
        switch (systemType) {
            case 2:
                List<AlarmSprayWater> list2 = alarmSprayWaterService.alarmSprayWaterListOne(companyName, handlingStatus, startDate, endDate);
                list = BeanMapperUtils.mapList(list2, AlarmSprayWater.class, AlarmHiddenDangerVo.class);
                break;
            case 3:
                List<AlarmHydrantWater> list3 = alarmHydrantWaterService.alarmHydrantWaterListOne(companyName, handlingStatus, startDate, endDate);
                list = BeanMapperUtils.mapList(list3, AlarmHydrantWater.class, AlarmHiddenDangerVo.class);
                break;
            case 4:
                List<AlarmSmokeControl> list4 = alarmSmokeControlService.alarmSmokeListOne(companyName, handlingStatus, startDate, endDate);
                list = BeanMapperUtils.mapList(list4, AlarmSmokeControl.class, AlarmHiddenDangerVo.class);
                break;
            case 5:
                List<AlarmElectricalFire> list5 = this.alarmElectricalFireListOne(companyName, handlingStatus, startDate, endDate);
                list = BeanMapperUtils.mapList(list5, AlarmElectricalFire.class, AlarmHiddenDangerVo.class);
                break;
            case 6:
                List<AlarmVideo> list6 = alarmVideoService.alarmVideoListOne(companyName, handlingStatus, startDate, endDate);
                list = BeanMapperUtils.mapList(list6, AlarmVideo.class, AlarmHiddenDangerVo.class);
                break;
        }
        return list;
    }

    @Override
    public Map<String, Object> alarmCount(String companyId, String table) {
        List<DataCountVo> dataCountVos = baseMapper.alarmCount(table, companyId);
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        for (int i = 0; i < dataCountVos.size(); i++) {
            if (dataCountVos.get(0).getId() == 0) {
                count1 = dataCountVos.get(0).getListCount();
            } else if (dataCountVos.get(0).getId() == 1) {
                count2 = dataCountVos.get(0).getListCount();
            }
        }
        count3 = count1 + count2;
        Map<String, Object> map = new HashMap<>();
        map.put("count", count3);
        map.put("processed", count2);
        map.put("untreated", count1);
        return map;
    }

    @Override
    public Map<String, Object> alarmFireCount(String companyId) {
        List<DataCountVo> dataCountVos = baseMapper.alarmFireCount(companyId);
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        for (int i = 0; i < dataCountVos.size(); i++) {
            if (dataCountVos.get(0).getId() == 0) {
                count1 = dataCountVos.get(0).getListCount();
            } else if (dataCountVos.get(0).getId() == 1) {
                count2 = dataCountVos.get(0).getListCount();
            }
        }
        count3 = count1 + count2;
        Map<String, Object> map = new HashMap<>();
        map.put("count", count3);
        map.put("processed", count2);
        map.put("untreated", count1);
        return map;
    }

    @Override
    public Integer electricalFireCount(String companyId, String startTime, String endTime) {
        LambdaQueryWrapper<AlarmElectricalFire> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AlarmElectricalFire::getCompanyId, companyId)
                .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), AlarmElectricalFire::getAlarmTime, startTime, endTime);
        int count = this.count(queryWrapper);
        return count;
    }


    @Override
    public List<DataVo> Alarmlist() {
        List<DataVo> list = new ArrayList<>();
        String companyId = baseUserCompanyService.companyId();
        LambdaQueryWrapper<AlarmElectricalFire> queryWrapperOne = Wrappers.lambdaQuery();
        queryWrapperOne.select(AlarmElectricalFire::getAlarmTime, AlarmElectricalFire::getDeviceCode,
                AlarmElectricalFire::getAlarmType, AlarmElectricalFire::getAddress,
                AlarmElectricalFire::getHandlingStatus, AlarmElectricalFire::getDeviceName,
                AlarmElectricalFire::getAttributeValue4)
                .eq(AlarmElectricalFire::getCompanyId, companyId)
                .orderByDesc(AlarmElectricalFire::getId)
                .last(" limit 1");
        List<AlarmElectricalFire> list1 = this.list(queryWrapperOne);
        for (int i = 0; i < list1.size(); i++) {
            DataVo dataVo = new DataVo();
            dataVo.setType1(list1.get(i).getAlarmTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            dataVo.setType2(list1.get(i).getDeviceCode());
            dataVo.setType3(OnlineMethod.alarmName(list1.get(i).getAlarmType()));
            dataVo.setType4(list1.get(i).getAddress());
            dataVo.setType5("-");
            dataVo.setType6(list1.get(i).getDeviceName() + "," + OnlineMethod.alarmName(list1.get(i).getAlarmType()) + ",高警值：" + list1.get(i).getAttributeValue4() + "" + OnlineMethod.company(list1.get(i).getAlarmType()));
            dataVo.setType7(list1.get(i).getHandlingStatus() == 1 ? "已处理" : "未处理");
            list.add(dataVo);
        }
        return list;
    }
}
