package com.nokia.tsl_data.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

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

import com.nokia.tsl_data.dao.CemMobileExperienceListMapper;
import com.nokia.tsl_data.dao.SysDataDictionaryRepository;
import com.nokia.tsl_data.dao.TargetTsRatioMapper;
import com.nokia.tsl_data.exception.LackOfDataRuntimeException;
import com.nokia.tsl_data.util.DateFormatUtil;

/**
 * 河北客户体验管理系统移网网络体验明细日信息_HE_D_CEM_MOBILE_EXPERIENCE_LIST
 */
@Service
public class CemMobileExperienceListService {
    
    @Autowired
    private CemMobileExperienceListMapper cemMobileExperienceListMapper;
    @Autowired
    private SysDataDictionaryRepository sysDataDictionaryRepository;
    @Autowired
    private TargetTsRatioMapper targetTsRatioRepository;
    @Autowired
    private UserCountService userCountService;

    public Map<String, List<Object>> getSheetData(String day) {
        // 1. 初始化存储
        Map<String, List<Object>> result = new HashMap<>();
        // 从1开始的，当前是当月的第几天
        int dayIndex = Integer.parseInt(day.substring(6, 8));
        // 初始化每个地市（按固定顺序）每天的工单量
        for (String area : sysDataDictionaryRepository.findAllCityName()) {
            List<Object> list = new ArrayList<>();
            for (int i = 0; i < dayIndex; i++) {
                list.add(0);
            }
            result.put(area, list);
        }
        // 初始化全省每天工作量
        List<Object> list0 = new ArrayList<>();
        for (int i = 0; i < dayIndex; i++) {
            list0.add(0);
        }
        result.put("全省", list0);
        // 读取数据库数据
        // 按照帐期查询数据
        List<Map<String, Object>> cityCountForStat = cemMobileExperienceListMapper.selectCityCountForStat(day);
        // 各地市每日
        for (Map<String,Object> map : cityCountForStat) {
            int dayId = Integer.parseInt(map.get("day_id").toString());
            result.get(map.get("city").toString()).set(dayId - 1, map.get("num"));
        }
        List<Map<String, Object>> allforStat = cemMobileExperienceListMapper.selectAllCountForStat(day);
        // 全省每日
        for (Map<String,Object> map : allforStat) {
            int dayId = Integer.parseInt(map.get("day_id").toString());
            result.get("全省").set(dayId - 1, map.get("num"));
        }
        // 地市总数
        List<Map<String, Object>> cityAllForStat = cemMobileExperienceListMapper.selectCityAllForStat(day);
        for (Map<String,Object> map : cityAllForStat) {
            result.get(map.get("city").toString()).add(map.get("num"));
        }
        // 全省总数
        int total = cemMobileExperienceListMapper.selectCountForStat(day);
        result.get("全省").add(total);
        // 3. 读取数据库 当月管理端用户数
        Map<String, Double> userCount = userCountService.getManagementUserCountForMonth(day.substring(0, 6));
        // 管理端用户数写入结果
        for (Entry<String, List<Object>> entry : result.entrySet()) {
            entry.getValue().add(userCount.get(entry.getKey()));
        }
        // 4. 万投率和本月预测
        Calendar calendar = DateFormatUtil.toCalendar(day, "yyyyMMdd");
        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 * calendar.getActualMaximum(Calendar.DAY_OF_MONTH) / calendar.get(Calendar.DAY_OF_MONTH);
            list.add(ycwtl);
        }
        // 5. 期望万投率
        List<Map<String,Object>> targetTsRatios = targetTsRatioRepository.findByMonthId(day.substring(0, 6));
        for (Map<String,Object> targetTsRatio : targetTsRatios) {
            result.get(targetTsRatio.get("city_name").toString()).add(targetTsRatio.get("service_request_target_ratio"));
        }
        // 6. 与目标差距
        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 = cemMobileExperienceListMapper.countForDay(day);
        if (count == 0) {
            throw new LackOfDataRuntimeException(String.format("cemMobileExperienceList 表缺少账期 %s 数据", day));
        }
    }
}
