package com.nokia.tsl_data.service;

import com.nokia.tsl_data.dao.HighQualityDataMapper;
import com.nokia.tsl_data.dao.HighQualityDataRepository;
import com.nokia.tsl_data.dao.HighQualityListDayMapper;
import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
import com.nokia.tsl_data.entity.HighQualityData;
import com.nokia.tsl_data.properties.TslDataProperties;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * 根据高质量明细表生产数据
 */
@Slf4j
@Service
public class HighQualityDataService {

    @Autowired
    private HighQualityDataRepository highQualityDataRepository;
    @Autowired
    private HighQualityDataMapper highQualityDataMapper;
    @Autowired
    private HighQualityListDayMapper highQualityListDayMapper;
    @Autowired
    private SysDataDictionaryRepository sysDataDictionaryRepository;
    @Autowired
    private TslDataProperties tslDataProperties;

    /**
     * 根据商定的算法生成数据
     */
    public void generateHighQualityData(String day) {
        // 1. 获取数据
        int countByDayId = highQualityDataRepository.countByDayId(day);
        if (countByDayId != 0) {
            throw new RuntimeException(
                    String.format("HighQualityData 帐期 %s 已存在 %s 条数据，需要先清除才能重新计算...", day, countByDayId));
        }
        List<HighQualityData> highQualityData = highQualityListDayMapper.selectHighQualityDataOfDay(day);
        // 保存到 high_quality_data 表
        highQualityDataRepository.saveAll(highQualityData);
        log.debug("HighQualityData {} 账期插入 {} 条数据...", day, highQualityData.size());
        // 2. 从 WorkFlowBasicData 更新地市/区县信息
        int countOfCityUpdated = highQualityDataMapper.updateHighQualityDataCityFromWorkFlowBasicData(day);
        int countOfRegionUpdated = highQualityDataMapper.updateHighQualityDataRegionFromWorkFlowBasicData(day);
        log.debug("根据 workflow 信息更新地市 {} 条, 更新区县 {} 条...", countOfCityUpdated, countOfRegionUpdated);
        // 3. 按照HighQualityList 更新地市/区县信息
        int countOfCityUpdated2 = highQualityDataMapper.updateHighQualityDataCityFromHighQualityListDay(day);
        int countOfRegionUpdated2 = highQualityDataMapper.updateHighQualityDataRegionFromHighQualityListDay(day);
        log.debug("根据 HighQualityList 信息更新地市 {} 条, 更新区县 {} 条...", countOfCityUpdated2, countOfRegionUpdated2);
        // 4. 仍无数据的配置默认值
        int countOfCityUpdated3 = highQualityDataMapper.updateHighQualityDataRegionFromDefault(day);
        log.debug("根据 默认规则 更新区县 {} 条...", countOfCityUpdated3);
    }

    /**
     * 计算区县投诉问题解决率
     */
    public List<List<Object>> generateCpIsOkOfRegion(String day) {
        // 地市 区县 解决率 达标值 与达标值差距 本月累计不满意工单量
        // 1. 获取全部的地市和区县
        Map<String, List<Object>> result = sysDataDictionaryRepository.findAllRegion();
        // 2. 解决率
        List<Map<String, Object>> maps = highQualityDataMapper.selectRateOfCpIsOkOfRegion(day);
        // 第一次遍历，将工单不为0的区县列出
        for (Map<String, Object> map : maps) {
            List<Object> objects = result.get(map.get("region").toString());
            if (objects == null) {
                log.error("发现 高品质详表存在的 区县{} 在 字典 high_quality_list_region 中不存在...", map);
            } else {
                objects.add(Double.parseDouble(map.get("rate").toString()));
            }
        }
        // 第二次遍历，补充工单为0的区县，响应率默认100%
        // 3. 满意度达标值 与达标值差距
        for (List<Object> list : result.values()) {
            if (list.size() == 2) {
                list.add(1.0);
            }
            // 写入达标值
            list.add(tslDataProperties.getResolutionCompliance());
            // 写入与达标值的差距
            list.add((double) list.get(2) - (double) list.get(3));
        }
        // 4. 本月累计不满意工单量
        List<Map<String, Object>> maps1 = highQualityDataMapper.selectCountOfCpNotOkOfRegion(day);
        for (Map<String, Object> map : maps1) {
            List<Object> objects = result.get(map.get("region").toString());
            if (objects == null) {
                log.error("发现 累计未解决工单量 存在的区县 {} 在 字典 high_quality_list_region 中不存在...", map);
            } else {
                objects.add(Integer.parseInt(map.get("count").toString()));
            }
        }
        for (List<Object> list : result.values()) {
            // 对于没有不满意工单的，直接补0
            if (list.size() == 5) {
                list.add(0);
            }
        }
        List<List<Object>> list = new ArrayList<>(result.values());
        list.sort(Comparator.comparingDouble(o -> (double) o.get(4)));
        return list;
    }

    /**
     * 计算区县投诉问题满意度
     */
    public List<List<Object>> generateCpSatisfactionOfRegion(String day) {
        // 地市 区县 满意度 达标值 与达标值差距 本月累计不满意工单量
        // 1. 获取全部的地市和区县
        Map<String, List<Object>> result = sysDataDictionaryRepository.findAllRegion();
        // 2. 满意度
        List<Map<String, Object>> maps = highQualityDataMapper.selectRateOfCpSatisfactionOfRegion(day);
        // 第一次遍历，将工单不为0的区县列出
        for (Map<String, Object> map : maps) {
            List<Object> objects = result.get(map.get("region").toString());
            if (objects == null) {
                log.error("发现 高品质详表存在的 区县{} 在 字典 high_quality_list_region 中不存在...", map);
            } else {
                objects.add(Double.parseDouble(map.get("rate").toString()));
            }
        }
        // 第二次遍历，补充工单为0的区县，响应率默认100%
        // 3. 满意度达标值 与达标值差距
        for (List<Object> list : result.values()) {
            if (list.size() == 2) {
                list.add(1.0);
            }
            // 写入达标值
            list.add(tslDataProperties.getSatisfiedCompliance());
            // 写入与达标值的差距
            list.add((double) list.get(2) - (double) list.get(3));
        }
        // 4. 本月累计不满意工单量
        List<Map<String, Object>> maps1 = highQualityDataMapper.selectCountOfCpNotSatisfactionOfRegion(day);
        for (Map<String, Object> map : maps1) {
            List<Object> objects = result.get(map.get("region").toString());
            if (objects == null) {
                log.error("发现 累计不满意工单量 存在的区县 {} 在 字典 high_quality_list_region 中不存在...", map);
            } else {
                objects.add(Integer.parseInt(map.get("count").toString()));
            }
        }
        for (List<Object> list : result.values()) {
            // 对于没有不满意工单的，直接补0
            if (list.size() == 5) {
                list.add(0);
            }
        }
        List<List<Object>> list = new ArrayList<>(result.values());
        list.sort(Comparator.comparingDouble(o -> (double) o.get(4)));
        return list;
    }

    /**
     * 计算区县投诉问题响应率
     */
    public List<List<Object>> generateCpTimelyContactOfRegion(String day) {
        // 地市 区县 响应率 达标值 与达标值差距 本月累计未响应工单量
        // 1. 获取全部的地市和区县
        Map<String, List<Object>> result = sysDataDictionaryRepository.findAllRegion();
        // 2. 响应率
        List<Map<String, Object>> maps = highQualityDataMapper.selectRateOfCpTimelyContactOfRegion(day);
        // 第一次遍历，将工单不为0的区县列出
        for (Map<String, Object> map : maps) {
            List<Object> objects = result.get(map.get("region").toString());
            if (objects == null) {
                log.error("发现 高品质详表存在的 区县{} 在 字典 high_quality_list_region 中不存在...", map);
            } else {
                objects.add(Double.parseDouble(map.get("rate").toString()));
            }
        }
        // 第二次遍历，补充工单为0的区县，响应率默认100%
        // 3. 响应率达标值 与达标值差距
        for (List<Object> list : result.values()) {
            if (list.size() == 2) {
                list.add(1.0);
            }
            // 写入达标值和与达标值的差距
            // 写入达标值
            list.add(tslDataProperties.getResponseCompliance());
            // 写入与达标值的差距
            list.add((double) list.get(2) - (double) list.get(3));
        }
        // 4. 本月累计未响应工单量
        List<Map<String, Object>> maps1 = highQualityDataMapper.selectCountOfCpNotTimelyContactOfRegion(day);
        for (Map<String, Object> map : maps1) {
            List<Object> objects = result.get(map.get("region").toString());
            if (objects == null) {
                log.error("发现 累计未响应工单量 存在的区县 {} 在 字典 high_quality_list_region 中不存在...", map);
            } else {
                objects.add(Integer.parseInt(map.get("count").toString()));
            }
        }
        for (List<Object> list : result.values()) {
            // 对于没有未响应工单的，直接补0
            if (list.size() == 5) {
                list.add(0);
            }
        }
        List<List<Object>> list = new ArrayList<>(result.values());
        list.sort(Comparator.comparingDouble(o -> (double) o.get(4)));
        return list;
    }

    public void deleteHighQualityData(String day) {
        highQualityDataMapper.deleteForDay(day);
    }
}
