package com.nokia.tsl_data.service;

import com.nokia.tsl_data.dao.*;
import com.nokia.tsl_data.exception.LackOfDataRuntimeException;
import com.nokia.tsl_data.properties.TslDataProperties;

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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 * 计算输出到文件的数据
 */
@Service
public class TslDataService {

    @Autowired
    private MobileComplaintMapper mobileComplaintMapper;
    @Autowired
    private SysDataDictionaryRepository sysDataDictionaryRepository;
    @Autowired
    private HighQualityCountMapper highQualityCountMapper;
    @Autowired
    private AvgDurationMapper avgDurationMapper;
    @Autowired
    private HighQualityCountService highQualityCountService;
    @Autowired
    private UserCountService userCountService;
    @Autowired
    private TargetTsRatioMapper targetTsRatioRepository;
    @Autowired
    private TslDataProperties tslDataProperties;

    /**
     * 客户端-投诉问题解决满意度 客户端-投诉问题解决率 客户端-投诉问题响应率
     */
    public List<List<List<Object>>> getSheet4_6Data(String day) {
        String realDay = day.substring(0, 4) + "-" + day.substring(4, 6) + "-" + day.substring(6);
        List<Map<String, Object>> data = highQualityCountMapper.selectClientRatioForDay(realDay);
        Map<String, Map<String, Object>> dataMap = new HashMap<>();
        for (Map<String, Object> map : data) {
            String key = (String) map.get("businoareaname");
            if (key.equals("雄安新区")) {
                dataMap.put("雄安", map);
            }
            dataMap.put(key, map);
        }
        List<List<List<Object>>> result = new ArrayList<>(3);
        List<List<Object>> list0;
        List<Object> list1;

        // 满意度
        list0 = new ArrayList<>();
        result.add(list0);
        // 地市满意度
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            list1 = new ArrayList<>(4);
            list0.add(list1);
            // 地市
            list1.add(0, area);
            // 满意率
            list1.add(1, dataMap.get(area).get("complaint_satisfied"));
            // 达标值
            list1.add(2, tslDataProperties.getSatisfiedCompliance());
            // 差距
            list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
        }
        // 逆序排序
        list0.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
        // 全省满意度
        list1 = new ArrayList<>(4);
        list0.add(list1);
        // 地市
        list1.add(0, "全省");
        // 满意率
        list1.add(1, dataMap.get("全省").get("complaint_satisfied"));
        // 达标值
        list1.add(2, tslDataProperties.getSatisfiedCompliance());
        // 差距
        list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));

        // 解决率
        list0 = new ArrayList<>();
        result.add(list0);
        // 地市解决率
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            list1 = new ArrayList<>(4);
            list0.add(list1);
            // 地市
            list1.add(0, area);
            // 解决率
            list1.add(1, dataMap.get(area).get("complaint_resolution"));
            // 达标值
            list1.add(2, tslDataProperties.getResolutionCompliance());
            // 差距
            list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
        }
        // 逆序排序
        list0.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
        // 全省解决率
        list1 = new ArrayList<>(4);
        list0.add(list1);
        // 地市
        list1.add(0, "全省");
        // 解决率
        list1.add(1, dataMap.get("全省").get("complaint_resolution"));
        // 达标值
        list1.add(2, tslDataProperties.getResolutionCompliance());
        // 差距
        list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));

        // 响应率
        list0 = new ArrayList<>();
        result.add(list0);
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            list1 = new ArrayList<>(4);
            list0.add(list1);
            // 地市
            list1.add(0, area);
            // 解决率
            list1.add(1, dataMap.get(area).get("complaint_response"));
            // 达标值
            list1.add(2, tslDataProperties.getResponseCompliance());
            // 差距
            list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));
        }
        // 逆序排序
        list0.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
        list1 = new ArrayList<>(4);
        list0.add(list1);
        list1.add(0, "全省");
        // 相应
        list1.add(1, dataMap.get("全省").get("complaint_response"));
        // 达标值
        list1.add(2, tslDataProperties.getResponseCompliance());
        // 差距
        list1.add(3, ((double) list1.get(1)) - (double) list1.get(2));

        return result;
    }

    /**
     * 超时工单情况
     */
    public List<List<Object>> getSheet3Data1(String day) {
        List<Map<String, Object>> data = mobileComplaintMapper.selectTimeoutTsCountForDay(day);
        Map<String, Map<String, Object>> dayMap = new HashMap<>();
        for (Map<String, Object> map : data) {
            dayMap.put((String) map.get("compl_area_local"), map);
        }
        List<List<Object>> result = new ArrayList<>();
        // 各地市数据
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            // 地市 工单数 超时工单数 超时工单占比
            List<Object> list = new ArrayList<>(4);
            result.add(list);

            list.add(0, area);
            // 获取该地市的数据--可能为null
            Map<String, Object> map = dayMap.get(area);
            if (map == null) {
                list.add(1, 0L);
                list.add(2, 0L);
                list.add(3, 0.0);
            } else {
                list.add(1, map.get("total_num"));
                list.add(2, map.get("timeout_num"));
                list.add(3, map.get("timeout_ratio"));
            }
        }
        // 逆序排序
        result.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
        // 全省数据
        List<Object> list = new ArrayList<>();
        result.add(list);
        // 地市
        list.add(0, "全省");
        // 工单数
        list.add(1, dayMap.get("全省").get("total_num"));
        // 超时工单数
        list.add(2, dayMap.get("全省").get("timeout_num"));
        // 超时工单占比
        list.add(3, dayMap.get("全省").get("timeout_ratio"));
        return result;
    }

    /**
     * 平均处理时长
     */
    public List<List<Object>> getSheet3Data2(String day) {
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        try {
            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 获取上个月的时间
        calendar.add(Calendar.MONTH, -1);
        String oldMonthId = new SimpleDateFormat("yyyyMM").format(calendar.getTime());
        List<Map<String, Object>> oldData = avgDurationMapper.selectOldTsDurationForMonth(oldMonthId);
        // 如果上月的平均处理时长数据不存在，需要插入
        if (oldData.size() == 0) {
            avgDurationMapper.insertOldTsDurationForMonth(oldMonthId);
            oldData = avgDurationMapper.selectOldTsDurationForMonth(oldMonthId);
        }
        List<Map<String, Object>> dayData = mobileComplaintMapper.selectTsDurationForDay(day);
        // 转化格式方便读取
        Map<String, Map<String, Object>> dayMap = new HashMap<>();
        Map<String, Map<String, Object>> preMap = new HashMap<>();
        for (Map<String, Object> map : dayData) {
            dayMap.put((String) map.get("compl_area_local"), map);
        }
        for (Map<String, Object> map : oldData) {
            preMap.put((String) map.get("city_name"), map);
        }
        List<List<Object>> result = new ArrayList<>();
        // 各地市数据
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            // 地市 上月平均处理时长 当月平均处理时长 涨幅
            List<Object> list = new ArrayList<>(4);
            result.add(list);
            list.add(0, area);
            list.add(1, preMap.get(area).get("avg_duration"));
            Map<String, Object> map = dayMap.get(area);
            if (map == null) {
                list.add(2, 0.0);
                list.add(3, 0.0);
            } else {
                list.add(2, dayMap.get(area).get("avg_duration"));
                list.add(3, ((double) list.get(2)) - (double) list.get(1));
            }
        }
        // 逆序排序
        result.sort((o1, o2) -> Double.compare((double) o2.get(3), (double) o1.get(3)));
        return result;
    }

    /**
     * 管理端-重复投诉率
     */
    public List<List<Object>> getSheet2Data(String day) {
        // 从数据库
        List<Map<String, Object>> dayData = mobileComplaintMapper.selectRepeatTsCountForDay(day);
        List<Map<String, Object>> preDayData = dayData;
        if (!day.endsWith("01")) {
            String preDay = String.valueOf(Integer.parseInt(day) - 1);
            preDayData = mobileComplaintMapper.selectRepeatTsCountForDay(preDay);
        }
        // 转化格式方便读取
        Map<String, Map<String, Object>> dayMap = new HashMap<>();
        Map<String, Map<String, Object>> preMap = new HashMap<>();
        for (Map<String, Object> map : dayData) {
            dayMap.put((String) map.get("compl_area_local"), map);
        }
        for (Map<String, Object> map : preDayData) {
            preMap.put((String) map.get("compl_area_local"), map);
        }
        List<List<Object>> result = new ArrayList<>();
        // 各地市数据
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            List<Object> list = new ArrayList<>(7);
            result.add(list);
            list.add(0, area);
            // 重复投诉工单数
            list.add(1, preMap.get(area).get("repeat_num"));
            list.add(2, dayMap.get(area).get("repeat_num"));
            // 重复投诉率
            list.add(3, preMap.get(area).get("repeat_ratio"));
            list.add(4, dayMap.get(area).get("repeat_ratio"));
            // 增量
            list.add(5, ((double) list.get(2)) - ((double) list.get(1)));
            list.add(6, ((double) list.get(4)) - ((double) list.get(3)));
        }
        // 排序--逆序
        result.sort((o1, o2) -> Double.compare((double) o2.get(6), (double) o1.get(6)));
        // 全省数据
        List<Object> list = new ArrayList<>(7);
        result.add(list);
        list.add(0, "全省");
        // 重复投诉工单数
        list.add(1, preMap.get("全省").get("repeat_num"));
        list.add(2, dayMap.get("全省").get("repeat_num"));
        // 重复投诉率
        list.add(3, preMap.get("全省").get("repeat_ratio"));
        list.add(4, dayMap.get("全省").get("repeat_ratio"));
        // 增量
        list.add(5, ((double) list.get(2)) - ((double) list.get(1)));
        list.add(6, ((double) list.get(4)) - ((double) list.get(3)));
        return result;
    }

    /**
     * 客户端-战略考核
     */
    public Map<String, List<Object>> getSheet1_1Data(String day) {
        // 各地市和全省数据
        Map<String, int[]> complaintsForDay = highQualityCountService.getComplaintsForDay(day);
        Map<String, List<Object>> result = new HashMap<>();
        // int dayIndex = Integer.parseInt(day.substring(6, 8));
        // 写入各地市数据
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            List<Object> list = new ArrayList<>();
            int[] js = complaintsForDay.get(area);
            for (int j : js) {
                list.add(j);
            }
            result.put(area, list);
        }
        // 写入全省数据
        result.put("全省", new ArrayList<>());
        int[] js = complaintsForDay.get("全省");
        for (int j : js) {
            result.get("全省").add(j);
        }
        // 客户端用户数
        Map<String, Double> customerUserCount = userCountService.getCustomerUserCountForMonth(day.substring(0, 6));
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            entry.getValue().add(customerUserCount.get(entry.getKey()));
        }

        // 获取当前月
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        try {
            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int actualMaximumDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        // 万投率和本月预测
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            List<Object> list = entry.getValue();
            int size = list.size();
            // 计算万投率
            double wtl = Double.parseDouble(list.get(size - 2).toString())
                    / Double.parseDouble(list.get(size - 1).toString());
            list.add(wtl);
            // 计算预测万投率
            double ycwtl = wtl * actualMaximumDayOfMonth / dayOfMonth;
            list.add(ycwtl);
        }

        // 期望万投率--从数据库取出来是一个字符串
        // 客户端目标投诉率
        List<Map<String,Object>> targetTsRatios = targetTsRatioRepository.findByMonthId(day.substring(0, 6));
        for (Map<String,Object> targetTsRatio : targetTsRatios) {
            result.get(targetTsRatio.get("city_name")).add(targetTsRatio.get("customer_target_ratio"));
        }

        // 与目标差距
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            List<Object> list = entry.getValue();
            int size = list.size();
            double cj = ((double) list.get(size - 2)) - ((double) list.get(size - 1));
            list.add(cj);
        }

        return result;
    }

    /**
     * 管理端-移网质量类
     */
    public Map<String, List<Object>> getSheet1Data(String day) {
        // 获取当前月
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        try {
            calendar.setTime(new SimpleDateFormat("yyyyMMdd").parse(day));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int actualMaximumDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        // monthId
        String monthId = new SimpleDateFormat("yyyyMM").format(calendar.getTime());
        // 读取数据库数据
        List<Map<String, Object>> cityTslForMonth = mobileComplaintMapper.selectCityTslForMonth(day);
        List<Map<String, Object>> allTslForMonth = mobileComplaintMapper.selectAllTslForMonth(day);
        List<Map<String, Object>> cityAllForMonth = mobileComplaintMapper.selectCityAllForMonth(day);
        int total = mobileComplaintMapper.selectAllForMonth(day);

        int dayIndex = Integer.parseInt(day.substring(6, 8));
        Map<String, List<Object>> result = new HashMap<>();
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            List<Object> list = new ArrayList<>();
            // 需要初始化一下
            for (int i = 0; i < dayIndex; i++) {
                list.add(0);
            }
            result.put(area, list);
        }
        result.put("全省", new ArrayList<>());

        // 各地市每日投诉量
        for (Map<String, Object> map : cityTslForMonth) {
            int dayId = Integer.parseInt(map.get("day_id").toString());
            result.get(map.get("compl_area_local").toString()).set(dayId - 1, map.get("num"));
        }
        // 全省每日投诉量
        for (Map<String, Object> map : allTslForMonth) {
            result.get("全省").add(map.get("num"));
        }
        // 各地市投诉总量
        for (Map<String, Object> map : cityAllForMonth) {
            result.get(map.get("compl_area_local").toString()).add(map.get("num"));
        }
        // 全省总量
        result.get("全省").add(total);
        // 当月管理端用户数
        Map<String, Double> userCount = userCountService.getManagementUserCountForMonth(monthId);
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            entry.getValue().add(userCount.get(entry.getKey()));
        }
        // 万投率和本月预测
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            List<Object> list = entry.getValue();
            int size = list.size();
            // 计算万投率
            double wtl = Double.parseDouble(list.get(size - 2).toString())
                    / Double.parseDouble(list.get(size - 1).toString());
            list.add(wtl);
            // 计算预测万投率
            double ycwtl = wtl * actualMaximumDayOfMonth / dayOfMonth;
            list.add(ycwtl);
        }
        // 期望万投率--从数据库取出来是一个字符串
        // 服务端目标投诉率
        List<Map<String,Object>> targetTsRatios = targetTsRatioRepository.findByMonthId(monthId);
        for (Map<String,Object> targetTsRatio : targetTsRatios) {
            result.get(targetTsRatio.get("city_name")).add(targetTsRatio.get("management_target_ratio"));
        }
        // 与目标差距
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            List<Object> list = entry.getValue();
            int size = list.size();
            double cj = ((double) list.get(size - 2)) - ((double) list.get(size - 1));
            list.add(cj);
        }
        return result;
    }

    /**
     * 按照账期检查数据
     */
    public void checkStatDayCount(String day) {
        int count = highQualityCountMapper.selectCountOfStatDay(day);
        if (count == 0) {
            throw new LackOfDataRuntimeException("high_quality_count_day", day);
        }
    }
}
