package com.persagy.dmp.rwd.parser.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.persagy.dmp.common.exception.BusinessException;
import com.persagy.dmp.common.model.data.RegionValue;
import com.persagy.dmp.common.utils.RegionUtil;
import com.persagy.dmp.rwd.parser.entity.ParserResult;

import java.io.IOException;
import java.util.List;

/**
 * 日期信息点 处理器
 * @author Charlie Yu
 * @date 2021-07-12
 */
public class DateInfoParser extends AbstractInfoDataParser {

    @Override
    protected void validateDefine(ParserResult result) throws IOException {
        // 格式默认为yyyyMMddHHmmss
        if(StrUtil.isBlank(result.getInfoDefine().getFormater())) {
            result.getInfoDefine().setFormater("yyyyMMddHHmmss");
        }
        String formatter = result.getInfoDefine().getFormater();
        // 数据源 - 应为区间列表格式
        List<RegionValue<String>> dataSource = formatRegionListValue(result.getInfoDefine().getDataSource(), String.class);
        // 区间格式校验
        if(!matchRegionDataFormat(formatter, dataSource)) {
            throw new BusinessException(StrUtil.format("信息点[{}]定义有误，数据源格式有误！", result.getInfoDefine().getCode()));
        }
    }

    @Override
    protected void validateValue(ParserResult result) throws IOException {
        String formatter = result.getInfoDefine().getFormater();
        // 数据源定义信息
        List<RegionValue<String>> dataSource = formatRegionListValue(result.getInfoDefine().getDataSource(), String.class);
        // 复数
        if(result.isMulti()) {
            // 复数区间
            if(result.isRegion()) {
                List<RegionValue<String>> valueList = formatRegionListValue(result.getValueInfo(), String.class);
                // 区间格式校验
                if (!matchRegionDataFormat(formatter, valueList)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据格式有误！", result.getInfoDefine().getCode()));
                }
                // 区间范围校验
                if (!RegionUtil.allContains(dataSource, valueList)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据有误，超出区间范围！", result.getInfoDefine().getCode()));
                }
            } else {
                // 复数非区间
                List<String> valueList = formatListValue(result.getValueInfo(), String.class);
                // 区间格式校验
                if (!matchDataFormat(formatter, valueList)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据格式有误！", result.getInfoDefine().getCode()));
                }
                // 区间范围校验
                if (!RegionUtil.allContain(dataSource, valueList)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据有误，超出区间范围！", result.getInfoDefine().getCode()));
                }
            }
        } else {
            // 单数区间
            if(result.isRegion()) {
                RegionValue<String> value = formatRegionValue(result.getValueInfo(), String.class);
                // 日期格式校验
                if (!matchRegionDataFormat(formatter, CollUtil.newArrayList(value))) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据格式有误！", result.getInfoDefine().getCode()));
                }
                // 区间范围校验
                if (!RegionUtil.anyContains(dataSource, value)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据有误，超出区间范围！", result.getInfoDefine().getCode()));
                }
            } else {
                // 单数非区间
                String value = formatValue(result.getValueInfo(), String.class);
                // 日期格式校验
                if (!matchDataFormat(formatter, value)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据格式有误！", result.getInfoDefine().getCode()));
                }
                // 区间范围校验
                if (!RegionUtil.anyContain(dataSource, value)) {
                    throw new BusinessException(StrUtil.format("信息点[{}]数据有误，超出区间范围！", result.getInfoDefine().getCode()));
                }
            }
        }
    }

    /**
     * 是否为指定格式日期区间
     * @param formatter 格式
     * @param regions 区间
     * @return
     */
    private boolean matchRegionDataFormat(String formatter, List<RegionValue<String>> regions) {
        if(CollUtil.isEmpty(regions) || StrUtil.isBlank(formatter)) {
            return true;
        }
        for(RegionValue<String> region:regions) {
            // 如果都匹配，则继续判断
            if(matchDataFormat(formatter, region.getStart()) && matchDataFormat(formatter, region.getEnd())) {
                continue;
            }
            return false;
        }
        return true;
    }

    /**
     * 是否为指定格式日期
     * @param formatter 格式
     * @param valueList 日期字符串
     * @return
     */
    private boolean matchDataFormat(String formatter, List<String> valueList) {
        if(CollUtil.isEmpty(valueList) || StrUtil.isBlank(formatter)) {
            return true;
        }
        for(String value:valueList) {
            // 如果匹配，则继续判断
            if(matchDataFormat(formatter, value)) {
                continue;
            }
            return false;
        }
        return true;
    }

    /**
     * 是否为指定格式日期
     * @param formatter 格式
     * @param value 日期字符串
     * @return
     */
    private boolean matchDataFormat(String formatter, String value) {
        // 日期可以任意匹配，因此只可判断长度是否一致
        return StrUtil.isBlank(formatter) || StrUtil.isBlank(value) || formatter.length() == value.length();
    }
}
