package com.usky.fire.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.core.util.BeanMapperUtils;
import com.usky.common.core.util.FileUtils;
import com.usky.common.core.util.GlobalUtils;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.fire.domain.AlarmFire;
import com.usky.fire.domain.BaseUserCompany;
import com.usky.fire.mapper.AlarmFireMapper;
import com.usky.fire.service.AlarmFireService;
import com.usky.fire.service.BaseUserCompanyService;
import com.usky.fire.service.util.OnlineMethod;
import com.usky.fire.service.vo.AlarmFireStatisticalVo;
import com.usky.fire.service.vo.AlarmFireVo;
import com.usky.fire.service.vo.DataVo;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
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 AlarmFireServiceImpl extends AbstractCrudService<AlarmFireMapper, AlarmFire> implements AlarmFireService {

    @Autowired
    private BaseUserCompanyService baseUserCompanyService;

    @Override
    public CommonPage<AlarmFireVo> alarmFireLowerList(String companyName, Integer handlingStatus, String startDate, String endDate,
                                                      Integer pageNum, Integer pageSize, String alarmType) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<String> alarmTypeList = new ArrayList<>();
        if (StringUtils.isNotBlank(alarmType)) {
            String[] alarmTypeArray = alarmType.split(",");
            for (int i = 0; i < alarmTypeArray.length; i++) {
                alarmTypeList.add(alarmTypeArray[i]);
            }
        }
        LambdaQueryWrapper<BaseUserCompany> QueryWrapper = Wrappers.lambdaQuery();
        QueryWrapper.select(BaseUserCompany::getCompanyId)
                .eq(BaseUserCompany::getUserId, SecurityUtils.getUserId());
        List<BaseUserCompany> comoanyList = baseUserCompanyService.list(QueryWrapper);
        List<AlarmFireVo> list = new ArrayList<>();
        CommonPage<AlarmFire> alarmFireList = new CommonPage<>();
        if (CollectionUtils.isNotEmpty(comoanyList)) {
            List<String> companyIdList = new ArrayList<>();
            for (int i = 0; i < comoanyList.size(); i++) {
                companyIdList.add(comoanyList.get(i).getCompanyId());
            }
            alarmFireList = this.alarmFireList(companyIdList, companyName, handlingStatus, startDate, endDate, pageNum, pageSize, alarmTypeList);
            for (int i = 0; i < alarmFireList.getRecords().size(); i++) {
                AlarmFireVo alarmFireVo = new AlarmFireVo();
                alarmFireVo.setId(alarmFireList.getRecords().get(i).getId());
                alarmFireVo.setDeviceCode(alarmFireList.getRecords().get(i).getDeviceCode());
                alarmFireVo.setCompanyName(alarmFireList.getRecords().get(i).getCompanyName());
                alarmFireVo.setCompanyId(alarmFireList.getRecords().get(i).getCompanyId());
                alarmFireVo.setAlarmTime(df.format(alarmFireList.getRecords().get(i).getAlarmTime()));
                alarmFireVo.setAlarmType(alarmFireList.getRecords().get(i).getAlarmType());
                alarmFireVo.setConten(alarmFireList.getRecords().get(i).getDeviceName() + "," + alarmFireList.getRecords().get(i).getAttributeValue4());
                alarmFireVo.setHandlingStatus(alarmFireList.getRecords().get(i).getHandlingStatus());
                alarmFireVo.setHandler(alarmFireList.getRecords().get(i).getHandler());
                if (alarmFireList.getRecords().get(i).getHandlingTime() != null) {
                    alarmFireVo.setHandlingTime(df.format(alarmFireList.getRecords().get(i).getHandlingTime()));
                } else {
                    alarmFireVo.setHandlingTime(null);
                }
                alarmFireVo.setFalseAlarm(alarmFireList.getRecords().get(i).getFalseAlarm());
                alarmFireVo.setHandlingContent(alarmFireList.getRecords().get(i).getHandlingContent());
                alarmFireVo.setSitePhoto(alarmFireList.getRecords().get(i).getSitePhoto());
                alarmFireVo.setPortNum(alarmFireList.getRecords().get(i).getPortNum());
                alarmFireVo.setHostNum(alarmFireList.getRecords().get(i).getHostNum());
                alarmFireVo.setLoopNum(alarmFireList.getRecords().get(i).getLoopNum());
                alarmFireVo.setPtNum(alarmFireList.getRecords().get(i).getPtNum());
                alarmFireVo.setAlarmTypeName(OnlineMethod.alarmName(alarmFireList.getRecords().get(i).getAlarmType()));
//            alarmFireVo.setSystemType(alarmFireList.getRecords().get(i).getSystemType());
//            alarmFireVo.setAddress(alarmFireList.getRecords().get(i).getAddress());
//            alarmFireVo.setAlarmStatus(alarmFireList.getRecords().get(i).getAlarmStatus());
//            alarmFireVo.setPointType(alarmFireList.getRecords().get(i).getPointType());
//            alarmFireVo.setHandlerPhone(alarmFireList.getRecords().get(i).getHandlerPhone());
                list.add(alarmFireVo);
            }
        }
        return new CommonPage<>(list, alarmFireList.getTotal(), pageSize, pageNum);
    }


    @Override
    public Map<String, Object> fireStatistics(String companyName, String alarmType, String startDate, String endDate) {
        List<String> alarmTypeList = new ArrayList<>();
        if (StringUtils.isNotBlank(alarmType)) {
            String[] alarmTypeArray = alarmType.split(",");
            for (int i = 0; i < alarmTypeArray.length; i++) {
                alarmTypeList.add(alarmTypeArray[i]);
            }
        }
        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());
            }
            untreated = this.fireCount(companyIdList, 0, alarmTypeList, companyName, startDate, endDate);
            processed = this.fireCount(companyIdList, 1, alarmTypeList, companyName, startDate, endDate);
            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> fireStatisticalChart(String alarmType, String startDate, String endDate) {
        List<String> alarmTypeList = new ArrayList<>();
        if (StringUtils.isNotBlank(alarmType)) {
            String[] alarmTypeArray = alarmType.split(",");
            for (int i = 0; i < alarmTypeArray.length; i++) {
                alarmTypeList.add(alarmTypeArray[i]);
            }
        }

        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());
            }
            List<String> alarmTypeListOne = new ArrayList<>();
            Integer selectStatus = 0;
            if (alarmTypeList.contains("100")) {
                selectStatus = 1;
                alarmTypeListOne.add("2");
                alarmTypeListOne.add("4");
            } else {
                alarmTypeListOne = alarmTypeList;
            }
            List<AlarmFireStatisticalVo> list = baseMapper.selectAlarmFireStatistical(companyIdList, alarmTypeListOne, startDate, endDate, selectStatus);
            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 updateAlarmFire(AlarmFire alarmFire) {
        if (alarmFire.getId() == 0) {
            LambdaQueryWrapper<AlarmFire> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.select(AlarmFire::getId)
                    .eq(AlarmFire::getDeviceCode, alarmFire.getDeviceCode())
                    .eq(AlarmFire::getAlarmType, alarmFire.getAlarmType())
                    .eq(AlarmFire::getHostNum, alarmFire.getHostNum())
                    .eq(AlarmFire::getLoopNum, alarmFire.getLoopNum())
                    .eq(AlarmFire::getPtNum, alarmFire.getPtNum())
                    .eq(AlarmFire::getPortNum, alarmFire.getPortNum());
            List<AlarmFire> 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(alarmFire.getHandlingContent());
                    list.get(i).setHandlerPhone(SecurityUtils.getLoginUser().getSysPerson().getLinkPhone());
                    list.get(i).setFalseAlarm(alarmFire.getFalseAlarm());
                    this.updateById(list.get(i));
                }
            }
        } else {
            alarmFire.setHandler(SecurityUtils.getUsername());
            alarmFire.setHandlingTime(LocalDateTime.now());
            alarmFire.setHandlingStatus(1);
            alarmFire.setHandlerPhone(SecurityUtils.getLoginUser().getSysPerson().getLinkPhone());
            this.updateById(alarmFire);
        }
    }


    @Override
    public List<AlarmFireVo> alarmFireLowerListExport(String companyName, Integer handlingStatus, String startDate, String endDate, String alarmType) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<String> alarmTypeList = new ArrayList<>();
        if (StringUtils.isNotBlank(alarmType)) {
            String[] alarmTypeArray = alarmType.split(",");
            for (int i = 0; i < alarmTypeArray.length; i++) {
                alarmTypeList.add(alarmTypeArray[i]);
            }
        }
        LambdaQueryWrapper<BaseUserCompany> QueryWrapper = Wrappers.lambdaQuery();
        QueryWrapper.select(BaseUserCompany::getCompanyId)
                .eq(BaseUserCompany::getUserId, SecurityUtils.getUserId());
        List<BaseUserCompany> comoanyList = baseUserCompanyService.list(QueryWrapper);
        List<AlarmFireVo> list = 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());
            }
            CommonPage<AlarmFire> alarmFireList = this.alarmFireList(companyIdList, companyName, handlingStatus, startDate, endDate, 0, 0, alarmTypeList);
            for (int i = 0; i < alarmFireList.getRecords().size(); i++) {
                AlarmFireVo alarmFireVo = new AlarmFireVo();
                alarmFireVo.setId(alarmFireList.getRecords().get(i).getId());
                alarmFireVo.setDeviceCode(alarmFireList.getRecords().get(i).getDeviceCode());
                alarmFireVo.setCompanyName(alarmFireList.getRecords().get(i).getCompanyName());
                alarmFireVo.setCompanyId(alarmFireList.getRecords().get(i).getCompanyId());
                alarmFireVo.setAlarmTime(df.format(alarmFireList.getRecords().get(i).getAlarmTime()));
                alarmFireVo.setAlarmType(alarmFireList.getRecords().get(i).getAlarmType());
                alarmFireVo.setConten(alarmFireList.getRecords().get(i).getDeviceName() + "," + alarmFireList.getRecords().get(i).getAttributeValue4());
                alarmFireVo.setHandlingStatus(alarmFireList.getRecords().get(i).getHandlingStatus());
                alarmFireVo.setHandler(alarmFireList.getRecords().get(i).getHandler());
                if (alarmFireList.getRecords().get(i).getHandlingTime() != null) {
                    alarmFireVo.setHandlingTime(df.format(alarmFireList.getRecords().get(i).getHandlingTime()));
                } else {
                    alarmFireVo.setHandlingTime(null);
                }
                alarmFireVo.setFalseAlarm(alarmFireList.getRecords().get(i).getFalseAlarm());
                alarmFireVo.setHandlingContent(alarmFireList.getRecords().get(i).getHandlingContent());
                alarmFireVo.setAlarmTypeName(OnlineMethod.alarmName(alarmFireList.getRecords().get(i).getAlarmType()));
                list.add(alarmFireVo);
            }
        }
        return list;
    }


    @Override
    public String alarmFireExport(String companyName, Integer handlingStatus, String startDate, String endDate, String alarmType, String exportTitle) {
        DateFormat dFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        Workbook workbook = null;
        File file = null;
        try {
            ExportParams params = new ExportParams(null, exportTitle);
            workbook = ExcelExportUtil.exportBigExcel(params, AlarmFireVo.class,
                    (o, i) -> {
                        List<AlarmFireVo> list = this.alarmFireLowerListExport(companyName, handlingStatus, startDate, endDate, alarmType);
                        return new ArrayList<>(BeanMapperUtils.mapList(list, AlarmFireVo.class, AlarmFireVo.class));
                    }, null);
            if (null != workbook) {
                file = FileUtils.getFile(GlobalUtils.getTempBaseDir(), String.format("%s-%s.xlsx", exportTitle, dFormat.format(System.currentTimeMillis()) + ""));
                FileUtils.createFile(file.getAbsolutePath());
                FileOutputStream allListingFileOutputStream = new FileOutputStream(file);
                workbook.write(allListingFileOutputStream);
            } else {
                throw new BusinessException("表格数据为空");
            }
        } catch (Exception e) {
            log.error("导出文件失败", e);
            throw new BusinessException("导出文件失败");
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    log.error("===export spec=== 关闭workbook失败", e);
                }
            }
        }
        return file.getName();
    }


    @Override
    public Integer fireCount(List<String> companyIdList, Integer handlingStatus, List<String> alarmTypeList, String companyName, String startDate, String endDate) {
        LambdaQueryWrapper<AlarmFire> queryWrapper = Wrappers.lambdaQuery();
        if (companyIdList.size() > 0) {
            queryWrapper.in(CollectionUtils.isNotEmpty(companyIdList), AlarmFire::getCompanyId, companyIdList);
        }
        if (CollectionUtils.isNotEmpty(alarmTypeList)) {
            if (alarmTypeList.contains("100")) {
                List<String> alarmTypeList1 = new ArrayList<>();
                alarmTypeList1.add("2");
                alarmTypeList1.add("4");
                queryWrapper.notIn(AlarmFire::getAlarmType, alarmTypeList1);
            } else {
                queryWrapper.in(AlarmFire::getAlarmType, alarmTypeList);
            }
        }
        queryWrapper.between(StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate), AlarmFire::getAlarmTime, startDate, endDate)
                .like(StringUtils.isNotBlank(companyName), AlarmFire::getCompanyName, companyName)
                .eq(handlingStatus != null, AlarmFire::getHandlingStatus, handlingStatus);
        int total = this.count(queryWrapper);
        return total;
    }


    @Override
    public CommonPage<AlarmFire> alarmFireList(List<String> companyIdList, String companyName, Integer handlingStatus, String startDate,
                                               String endDate, Integer pageNum, Integer pageSize, List<String> alarmTypeList) {
        LambdaQueryWrapper<AlarmFire> queryWrapper = Wrappers.lambdaQuery();
        if (companyIdList.size() > 0) {
            queryWrapper.in(AlarmFire::getCompanyId, companyIdList);
        }
        if (StringUtils.isNotBlank(companyName)) {
            queryWrapper.like(AlarmFire::getCompanyName, companyName);
        }
        if (handlingStatus != null) {
            queryWrapper.eq(AlarmFire::getHandlingStatus, handlingStatus);
        }

        if (alarmTypeList.size() > 0) {
            if (alarmTypeList.contains("100")) {
                List<String> alarmTypeList1 = new ArrayList<>();
                alarmTypeList1.add("2");
                alarmTypeList1.add("4");
                queryWrapper.notIn(AlarmFire::getAlarmType, alarmTypeList1);
            } else {
                queryWrapper.in(AlarmFire::getAlarmType, alarmTypeList);
            }
        }

        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            queryWrapper.between(AlarmFire::getAlarmTime, startDate, endDate);
        }
        int total = this.count(queryWrapper);
        queryWrapper.orderByDesc(AlarmFire::getId);
        if (pageNum != null && pageNum != 0 && pageSize != null && pageSize != 0) {
            Integer startFate = OnlineMethod.getStartFate(pageNum, pageSize);
            queryWrapper.last("limit " + startFate + "," + pageSize);
        }
        List<AlarmFire> list = this.list(queryWrapper);
        return new CommonPage<>(list, total, pageSize, pageNum);
    }

    @Override
    public Integer fireAlarmCount(String companyId, Integer handlingStatus, String alarmType, String startTime, String endTime) {
        LambdaQueryWrapper<AlarmFire> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AlarmFire::getCompanyId, companyId)
                .eq(handlingStatus != null, AlarmFire::getHandlingStatus, handlingStatus)
                .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), AlarmFire::getAlarmTime, startTime, endTime);
        if (alarmType.equals("100")) {
            queryWrapper.notIn(AlarmFire::getAlarmType, 2, 3);
        }else if (alarmType.equals("101")){

        }else {
            queryWrapper.eq(StringUtils.isNotBlank(alarmType), AlarmFire::getAlarmType, alarmType);
        }
        int count = this.count(queryWrapper);
        return count;
    }

    @Override
    public List<DataVo> Alarmlist() {
        List<DataVo> list = new ArrayList<>();
        String companyId = baseUserCompanyService.companyId();
        LambdaQueryWrapper<AlarmFire> queryWrapperOne = Wrappers.lambdaQuery();
        queryWrapperOne.select(AlarmFire::getAlarmTime, AlarmFire::getDeviceCode,
                AlarmFire::getAlarmType, AlarmFire::getAddress,
                AlarmFire::getHandlingStatus, AlarmFire::getDeviceName,
                AlarmFire::getAttributeValue4, AlarmFire::getPortNum)
                .eq(AlarmFire::getCompanyId, companyId)
                .orderByDesc(AlarmFire::getId)
                .last(" limit 2");
        List<AlarmFire> 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(list1.get(i).getAttributeValue2());
            dataVo.setType4(list1.get(i).getAddress());
            dataVo.setType5(list1.get(i).getPortNum());
            dataVo.setType6(list1.get(i).getDeviceName() + "," + list1.get(i).getAttributeValue4());
            dataVo.setType7(list1.get(i).getHandlingStatus() == 1 ? "已处理" : "未处理");
            list.add(dataVo);
        }
        return list;
    }
}
