package com.yeejoin.equipmanage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yeejoin.equipmanage.common.dto.AnalysisReportLogDto;
import com.yeejoin.equipmanage.common.entity.AnalysisReportLog;
import com.yeejoin.equipmanage.common.entity.UploadFile;
import com.yeejoin.equipmanage.common.entity.publics.BaseEntity;
import com.yeejoin.equipmanage.common.enums.AnalysisReportEnum;
import com.yeejoin.equipmanage.common.utils.DateUtils;
import com.yeejoin.equipmanage.mapper.AnalysisReportLogMapper;
import com.yeejoin.equipmanage.mapper.AnalysisReportMonthMapper;
import com.yeejoin.equipmanage.mapper.AnalysisReportSummaryMapper;
import com.yeejoin.equipmanage.mapper.FireFightingSystemMapper;
import com.yeejoin.equipmanage.service.IAnalysisReportLogService;
import com.yeejoin.equipmanage.service.IFireFightingSystemService;
import com.yeejoin.equipmanage.service.IUploadFileService;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 报告流水表 服务实现类
 *
 * @author duanwei
 * @date 2021-05-26
 */
@Service
public class AnalysisReportLogServiceImpl extends ServiceImpl<AnalysisReportLogMapper, AnalysisReportLog> implements IAnalysisReportLogService {

    @Autowired
    IFireFightingSystemService fireFightingSystemService;

    @Autowired
    AnalysisReportMonthMapper analysisReportMonthMapper;

    @Autowired
    AnalysisReportSummaryMapper analysisReportSummaryMapper;

    @Autowired
    AnalysisReportLogMapper analysisReportLogMapper;
    @Autowired
    IUploadFileService iUploadFileService;

    @Autowired
    FireFightingSystemMapper fireFightingSystemMapper;

    @Value("classpath:/json/systemIndex.json")
    private Resource systemIndex;

    @Override
    public IPage<AnalysisReportLog> listPage(Page page, AnalysisReportLog analysisReportLog) {

        LambdaQueryWrapper<AnalysisReportLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AnalysisReportLog::getReportType, analysisReportLog.getReportType());
        if (analysisReportLog.getStartDate() != null && analysisReportLog.getEndDate() != null) {
            queryWrapper.ge(AnalysisReportLog::getStartDate, analysisReportLog.getStartDate());
            queryWrapper.le(AnalysisReportLog::getEndDate, analysisReportLog.getEndDate());
        }
        queryWrapper.select().orderByDesc(BaseEntity::getCreateDate);

        return this.baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public void generateReport(AnalysisReportEnum reportEnum, Date beginDate, Date endDate) {
        this.saveAnalysisReportLog(reportEnum, beginDate, endDate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateMonthReport(AnalysisReportEnum reportEnum, Date beginDate, Date endDate) throws ParseException {
        // 0.保存日志
        this.saveAnalysisReportLog(reportEnum, beginDate, endDate);
        // 创建月分析统计报告数据
        // 1、 查询消防系统表，捞出所有系统，新增字段，存放自定义用的告警指标模糊查询指标key，逗号分隔
        List<Map<String, Object>> list = fireFightingSystemMapper.selectSystemByBizOrgCode(null);
        // 2、循环插入 wl_analysis_report_month、wl_analysis_report_summary
        String beginDateStr = DateUtils.dateFormat(beginDate,DateUtils.DATE_PATTERN);
        String endDateStr = DateUtils.dateFormat(endDate,DateUtils.DATE_PATTERN);
        String json = null;
        try {
            json = IOUtils.toString(systemIndex.getInputStream(), java.lang.String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取系统对应指标配置信息
        List<Map> indicatorConfiguration = JSONObject.parseArray(json, Map.class);
        list.forEach(f -> {
            // 具体系统对应指标
            List<Map> collect = indicatorConfiguration.stream().
                    filter(index -> index.get("code").equals(String.valueOf(f.get("typeCode")))).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(collect)) {
                String indicator = String.valueOf(collect.get(0).get("index"));
                analysisReportMonthMapper.insertSystemMonthData(new ArrayList<>(Arrays.asList(indicator.split(","))), beginDateStr, endDateStr, Long.valueOf(f.get("id").toString()));
                analysisReportSummaryMapper.insertSystemMonthSummaryData(new ArrayList<>(Arrays.asList(indicator.split(","))), beginDateStr, endDateStr, Long.valueOf(f.get("id").toString()));
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateMonthReportTest(AnalysisReportEnum reportEnum, Date beginDate, Date endDate,Date now,int num) throws ParseException {
        // 0.保存日志
        this.saveAnalysisReportLog(reportEnum, beginDate, endDate);
        // 创建月分析统计报告数据
        // 1、 查询消防系统表，捞出所有系统，新增字段，存放自定义用的告警指标模糊查询指标key，逗号分隔
        List<Map<String, Object>> list = fireFightingSystemMapper.selectSystemByBizOrgCode(null);
        // 2、循环插入 wl_analysis_report_month、wl_analysis_report_summary
        String beginDateStr = DateUtils.dateFormat(beginDate,DateUtils.DATE_PATTERN);
        String endDateStr = DateUtils.dateFormat(endDate,DateUtils.DATE_PATTERN);
        String json = null;
        try {
            json = IOUtils.toString(systemIndex.getInputStream(), java.lang.String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 获取系统对应指标配置信息
        List<Map> indicatorConfiguration = JSONObject.parseArray(json, Map.class);
        list.forEach(f -> {
            // 具体系统对应指标
            List<Map> collect = indicatorConfiguration.stream().
                    filter(index -> index.get("code").equals(String.valueOf(f.get("typeCode")))).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(collect)) {
                String indicator = String.valueOf(collect.get(0).get("index"));
                analysisReportMonthMapper.insertSystemMonthData(new ArrayList<>(Arrays.asList(indicator.split(","))), beginDateStr, endDateStr, Long.valueOf(f.get("id").toString()));
                analysisReportSummaryMapper.insertSystemMonthSummaryData(new ArrayList<>(Arrays.asList(indicator.split(","))), beginDateStr, endDateStr, Long.valueOf(f.get("id").toString()));
            }
        });
    }

    private void saveAnalysisReportLog(AnalysisReportEnum reportEnum, Date beginDate, Date endDate) {
        AnalysisReportLog reportLog = new AnalysisReportLog();
        reportLog.setName(reportEnum.getName());
        reportLog.setReportType(reportEnum.getType());
        reportLog.setStartDate(beginDate);
        reportLog.setEndDate(endDate);
        reportLog.setReportDateDesc(buildReportDateDesc(reportEnum, beginDate, endDate));


        this.save(reportLog);
    }

    private String buildReportDateDesc(AnalysisReportEnum reportEnum, Date beginDate, Date endDate) {
        StringBuilder desc = new StringBuilder();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginDate);
        switch (reportEnum) {
            case DAY_REPORT:
                desc.append(calendar.get(Calendar.YEAR));
                desc.append("年");
                desc.append(calendar.get(Calendar.MONTH) + 1);
                desc.append("月");
                desc.append(calendar.get(Calendar.DAY_OF_MONTH));
                desc.append("日");
                break;
            case WEEK_REPORT:
                desc.append(calendar.get(Calendar.YEAR));
                desc.append("年");
                desc.append(calendar.get(Calendar.MONTH) + 1);
                desc.append("月");
                desc.append(calendar.get(Calendar.DAY_OF_MONTH));
                desc.append(" - ");
                calendar.setTime(endDate);
                desc.append(calendar.get(Calendar.YEAR));
                desc.append("年");
                desc.append(calendar.get(Calendar.MONTH) + 1);
                desc.append("月");
                desc.append(calendar.get(Calendar.DAY_OF_MONTH));
                desc.append("日");
                break;
            case MONTH_REPORT:
                desc.append(calendar.get(Calendar.YEAR));
                desc.append("年");
                desc.append(calendar.get(Calendar.MONTH) + 1);
                desc.append("月");
                break;
            default:
                break;
        }
        return desc.toString();
    }

    @Override
    public IPage<AnalysisReportLogDto> iotReportPage(Page page, AnalysisReportLogDto dto) {
        IPage<AnalysisReportLogDto> analysisReportLogDtoIPage = analysisReportLogMapper.iotReportPage(page, dto);
        List<AnalysisReportLogDto> records = analysisReportLogDtoIPage.getRecords();
        records.forEach(e->{
                if (e.getReportType() == 0){
                    this.setReportUrl(e,dto.getStationCode(),"d-report");
                      }
                if (e.getReportType() == 1) {
                    this.setReportUrl(e,dto.getStationCode(),"w-report");
                }
                if (e.getReportType() == 2){
                    this.setReportUrl(e,dto.getStationCode(),"m-report");
                }
        });
        return analysisReportLogDtoIPage;
    }

    private void setReportUrl(AnalysisReportLogDto dto,String bizOrgCode,String objType ){
        LambdaQueryWrapper<UploadFile> wrapper = new LambdaQueryWrapper<>();
        // String[] types = new String[]{"w-report","d-report","m-report"};
        //wrapper.in(UploadFile::getObjectType, Arrays.asList(types));
        wrapper.eq(UploadFile::getDepartmentOrgcode,bizOrgCode);
        wrapper.eq(UploadFile::getObjectType,objType);
        List<UploadFile> uploadFiles = iUploadFileService.getBaseMapper().selectList(wrapper);
        uploadFiles.forEach(i->{
            if (DateUtils.dateCompare(new Date(dto.getStartDate().getTime()), new Date(i.getObjectId())) == 0){
                dto.setUrl(i.getUrl());
            }
        });

    }
}
