package com.yeejoin.amos.knowledgebase.face.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.knowledgebase.face.model.KnowledgeDocContentModel;
import com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagInstanceModel;
import com.yeejoin.amos.knowledgebase.face.model.KnowlegeStatisticsRecordModel;
import com.yeejoin.amos.knowledgebase.face.orm.dao.StatisticsRecordMapper;
import com.yeejoin.amos.knowledgebase.face.orm.entity.KnowledgeDocContent;
import com.yeejoin.amos.knowledgebase.face.orm.entity.KnowlegeStatisticsRecord;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.DateUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.*;


/**
 * <p>
 * 标签分组 服务类
 * </p>
 *
 * @author 子杨
 * @since 2020-08-05
 */
@Component
public class StatisticsRecordService extends BaseService<KnowlegeStatisticsRecordModel, KnowlegeStatisticsRecord, StatisticsRecordMapper> {

    /*@Autowired
    private DocContentService docContentService;

    private final Logger logger = LogManager.getLogger(StatisticsRecordService.class);

    *//**
     * 灾情标记
     *//*
    public static final String TAG_NAME_TIME = "时间";
    public static final String STATISTICS_DISASTER_COUNT = "DISASTER_RECORD";

    *//**
     * 燃烧物质分类
     *//*
    public static final String TAG_NAME_BURNING = "燃烧物质";
    public static final String STATISTICS_BURNING_CATEGORY = "BURNING_RECORD";

    *//**
     * 参战车辆统计
     *//*
    public static final String TAG_NAME_POWER = "参战车辆";
    public static final String STATISTICS_POWER_SUM = "POWER_RECORD";

    *//**
     * 伤亡人数统计
     *//*
    public static final String TAG_NAME_CASUALTIES = "人员伤亡情况 含亡人";
    public static final String STATISTICS_CASUALTIES_SUM = "CASUALTIES_RECORD";

    *//**
     * 灭火药剂统计
     *//*
    public static final String TAG_NAME_EXTINGUISHING = "使用的灭火药剂数量";
    public static final String STATISTICS_EXTINGUISHING_SUM = "EXTINGUISHING_RECORD";

    *//**
     * 过火面积统计
     *//*
    public static final String TAG_NAME_AREA = "过火面积";
    public static final String STATISTICS_AREA_COUNT = "FIRE_AREA_RECORD";

    *//**
     * 到场时间分类
     *//*
    public static final String TAG_NAME_PICKUP = "接警时间";
    public static final String TAG_NAME_PRESENT = "到场时间";
    public static final String STATISTICS_PRESENT_CATEGORY = "PRESENT_TIME_RECORD";


    public static final String DATE_GROUP_BY_DAY = "day";
    public static final String DATE_GROUP_BY_MONTH = "month";

    @Value("${diy-config.report.record-data}")
    private boolean needRecord;

    *//** 根据文档标签添加对应的记录 *//*
    private void addRecordWithDocValueTag(List<KnowledgeTagInstanceModel> docTags, Long docSeq) {
        //找出预定义的所有标签
        Map<Object, KnowledgeTagInstanceModel> tagMap = Bean.listToMap(docTags, "tagName", KnowledgeTagInstanceModel.class);
        KnowledgeTagInstanceModel tagTime = tagMap.get(TAG_NAME_TIME);
        if (ValidationUtil.isEmpty(tagTime)) {
            return;
        }
        Object timeObj = getValueFromTag(tagTime);
        if (ValidationUtil.isEmpty(timeObj) || !(timeObj instanceof Date)) {
            return;
        }
        Date disasterTime = (Date) timeObj;
        //记录灾情
        insertSumTypeRecord(docSeq, disasterTime, STATISTICS_DISASTER_COUNT, 1.0, 1);
        //记录燃烧物质
        KnowledgeTagInstanceModel tagBurning = tagMap.get(TAG_NAME_BURNING);
        if (!ValidationUtil.isEmpty(tagBurning)) {
            insertCategoryTypeRecord(docSeq, disasterTime, STATISTICS_BURNING_CATEGORY, getValueFromTag(tagBurning));
        }
        //记录参战车辆
        KnowledgeTagInstanceModel tagPower = tagMap.get(TAG_NAME_POWER);
        if (!ValidationUtil.isEmpty(tagPower)) {
            insertSumTypeRecord(docSeq, disasterTime, STATISTICS_POWER_SUM, getValueFromTag(tagPower), 1);
        }
        //记录伤亡人数
        KnowledgeTagInstanceModel tagCasualties = tagMap.get(TAG_NAME_CASUALTIES);
        if (!ValidationUtil.isEmpty(tagCasualties)) {
            insertSumTypeRecord(docSeq, disasterTime, STATISTICS_CASUALTIES_SUM, getValueFromTag(tagCasualties), 1);
        }
        //记录灭火药剂数量
        KnowledgeTagInstanceModel tagExtinguishing = tagMap.get(TAG_NAME_EXTINGUISHING);
        if (!ValidationUtil.isEmpty(tagExtinguishing)) {
            insertSumTypeRecord(docSeq, disasterTime, STATISTICS_EXTINGUISHING_SUM, getValueFromTag(tagExtinguishing), 1);
        }
        //记录过火面积
        KnowledgeTagInstanceModel tagArea = tagMap.get(TAG_NAME_AREA);
        if (!ValidationUtil.isEmpty(tagArea)) {
            insertSumTypeRecord(docSeq, disasterTime, STATISTICS_AREA_COUNT, getValueFromTag(tagArea), 1);
        }
        //记录到场时间
        KnowledgeTagInstanceModel tagPickup = tagMap.get(TAG_NAME_PICKUP);
        KnowledgeTagInstanceModel tagPresent = tagMap.get(TAG_NAME_PRESENT);
        if (!ValidationUtil.isEmpty(tagPickup) && !ValidationUtil.isEmpty(tagPresent)) {
            Object pickTimeObj = getValueFromTag(tagPickup);
            Object presentTimeObj = getValueFromTag(tagPresent);
            if (!ValidationUtil.isEmpty(pickTimeObj) && pickTimeObj instanceof Date
                    && !ValidationUtil.isEmpty(presentTimeObj) && presentTimeObj instanceof Date) {
                long presentTimeByMinute = (long) Math.ceil((((Date) presentTimeObj).getTime() - ((Date) pickTimeObj).getTime()) / 1000.0 / 60.0);
                insertCategoryTypeRecord(docSeq, disasterTime, STATISTICS_PRESENT_CATEGORY, presentTimeByMinute);
            }
        }
    }

    *//** 获取标签值 *//*
    private Object getValueFromTag(KnowledgeTagInstanceModel tag) {
        if (ValidationUtil.isEmpty(tag)
                || !ValidationUtil.equals(tag.getTagType(), TagService.TAG_TYPE_VALUE)
                || ValidationUtil.isEmpty(tag.getTagValues())) {
            return null;
        }
        String fieldName = tag.getTagValues().get(0).getFieldName();
        String tagValue = tag.getTagValues().get(0).getTagValue();
        if (ValidationUtil.isEmpty(fieldName)
                || ValidationUtil.isEmpty(tagValue)) {
            return null;
        }
        switch (fieldName) {
            case TagValueService.VALUE_TAG_FIELD_DATE_H:
                try {
                    return DateUtil.formatStringToDate(tagValue, null);
                } catch (Exception e) {
                    logger.error("报表统计：时间格式标签值解析出错");
                    return null;
                }
            case TagValueService.VALUE_TAG_FIELD_SINGLEVALUE:
                try {
                    return Double.parseDouble(tagValue);
                } catch (Exception e) {
                    logger.error("报表统计：数字格式标签值解析出错");
                    return null;
                }
            case TagValueService.VALUE_TAG_FIELD_TEXT:
                return tagValue;
            default:
                return null;
        }
    }

    *//** 插入分类统计记录 *//*
    private void insertCategoryTypeRecord(Long docSeq, Date disasterTime, String recordName, Object category) {
        KnowlegeStatisticsRecordModel recordModel = new KnowlegeStatisticsRecordModel();
        recordModel.setDocSeq(docSeq);
        recordModel.setDisasterTime(disasterTime);
        recordModel.setRecordName(recordName);
        recordModel.setCategoryValue(String.valueOf(category));
        recordModel.setValueWeight(1);
        recordModel.setCountValue(1L);
        this.createWithModel(recordModel);
    }


    *//** 插入数量统计记录 *//*
    private void insertSumTypeRecord(Long docSeq, Date disasterTime, String recordName, Object numObj, Integer weight) {
        if (!ValidationUtil.isEmpty(numObj) && numObj instanceof Double) {
            Long num = ((Double) numObj).longValue();
            KnowlegeStatisticsRecordModel recordModel = new KnowlegeStatisticsRecordModel();
            recordModel.setDocSeq(docSeq);
            recordModel.setDisasterTime(disasterTime);
            recordModel.setRecordName(recordName);
            recordModel.setCountValue(num);
            recordModel.setValueWeight(weight);
            this.createWithModel(recordModel);
        }
    }

    *//**
     * 根据文档id删除相关记录
     *//*
    public void deleteRecordsByDocIds(List<KnowledgeDocContentModel> docs) {
        if (!ValidationUtil.isEmpty(docs)) {
            Set ids = Bean.listToMap(docs, "sequenceNbr", KnowledgeDocContentModel.class).keySet();
            QueryWrapper<KnowlegeStatisticsRecord> wrapper = new QueryWrapper<>();
            wrapper.in("doc_seq", ids);
            this.getBaseMapper().delete(wrapper);
        }
    }

    *//**
     * 初始化统计数据记录
     *
     * @return
     *//*
    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public boolean init() {
        this.getBaseMapper().deleteAll();
        //扫描所有已发布文档相关的统计型标签
        QueryWrapper<KnowledgeDocContent> wrapper = new QueryWrapper<>();
        wrapper.eq("doc_status", DocContentService.DOC_STATUS_PUBLISHED);
        int count = docContentService.count(wrapper);
        int finishNmu = 0;
        int current = 0;
        while (count > finishNmu) {
            Page page = new Page(current++, 30);
            IPage resPage = docContentService.page(page, wrapper);
            List<KnowledgeDocContent> records = resPage.getRecords();
            Set ids = Bean.listToMap(records, "sequenceNbr", KnowledgeDocContent.class).keySet();
            saveRecordsByDocIds(ids);
            finishNmu += records.size();
        }
        return true;
    }

    public boolean addDocRecords(List<KnowledgeDocContentModel> docs) {
        if (!ValidationUtil.isEmpty(docs)) {
            Set ids = Bean.listToMap(docs, "sequenceNbr", KnowledgeDocContentModel.class).keySet();
            saveRecordsByDocIds(ids);
        }
        return true;
    }

    private void saveRecordsByDocIds(Collection ids) {
        if (!needRecord) {
            return;
        }
        for (Object id : ids) {
            KnowledgeDocContentModel docContentModel = docContentService.queryOneDocDetail((Long) id);
            if (ValidationUtil.isEmpty(docContentModel)) {
                continue;
            }
            addRecordWithDocValueTag(docContentModel.getDocTags(), docContentModel.getSequenceNbr());
        }
    }

    *//**
     * 查询灾情统计/同比/环比
     *
     * @return
     *//*
    public Map<String, Object> selectDisasterCount() {
        return this.getBaseMapper().selectDisasterCount();
    }

    public List<Map<String, Object>> selectCategoryByName(String recordName) {
        return this.getBaseMapper().selectCategoryByName(recordName);
    }

    *//**
     * 分类汇总
     *//*
    public List<Map<String, Object>> selectCountByTypeAndDateRange(String dateType, String dateRangeLeft, String dateRangeRight, String recordName) {
        Map<String, Object> queryMap = new HashMap<>();
        switch (dateType) {
            case DATE_GROUP_BY_MONTH:
                queryMap.put("format", "%Y-%m");
                break;
            default:
                queryMap.put("format", "%Y-%m-%d");
                break;
        }
        if(!ValidationUtil.isEmpty(dateRangeLeft)){
            try {
                queryMap.put("dateRangeLeft", DateUtil.formatStringToDate(dateRangeLeft, null));
            } catch (Exception e) {
                throw new BadRequest("时间参数格式有误");
            }
        }
        if(!ValidationUtil.isEmpty(dateRangeRight)){
            try {
                queryMap.put("dateRangeRight", DateUtil.formatStringToDate(dateRangeRight, null));
            } catch (Exception e) {
                throw new BadRequest("时间参数格式有误");
            }
        }
        queryMap.put("recordName", recordName);
        return this.getBaseMapper().selectCountByNameAndDateRange(queryMap);
    }*/
}
