package com.jsc.oscm.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jsc.oscm.dao.LogRepository;
import com.jsc.oscm.dao.TaskRepository;
import com.jsc.oscm.entity.MetaDict;
import com.jsc.oscm.entity.TargetSocial;
import com.jsc.oscm.entity.TargetWebsite;
import com.jsc.oscm.entity.Task;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class OverviewService {
    @Resource
    LogRepository logRepository;

    @Resource
    TaskRepository taskRepository;

    @Resource
    TargetWebsiteService targetWebsiteService;

    @Resource
    TargetSocialService targetSocialService;

    @Resource
    LogService logService;

    @Resource
    ProjectService projectService;

    @Resource
    TaskService taskService;

    @Resource
    CloudServerService cloudServerService;

    @Resource
    MetaDictService metaDictService;

    @Value("${crawl.website.project}")
    String websiteSpiderName;

    final static long ONE_DAY_SECONDS = (long) 24 * 60 * 60 * 1000;

    public JSONObject getHomepageStats() {
        Long serverCount = cloudServerService.queryAllHostCount();
        JSONObject serverResult = new JSONObject();
        serverResult.put("positive", serverCount);
        serverResult.put("all", serverCount);
        Long projectCount = projectService.findAllCount();
        JSONObject projectResult = new JSONObject();
        projectResult.put("positive", projectCount);
        projectResult.put("all", projectCount);
        TargetWebsite targetWebsite = new TargetWebsite();
        Long websiteAll = targetWebsiteService.queryCount(targetWebsite);
        targetWebsite.setStatus(0);
        Long websitePositive = targetWebsiteService.queryCount(targetWebsite);
        JSONObject targetWebsiteResult = new JSONObject();
        targetWebsiteResult.put("positive", websitePositive);
        targetWebsiteResult.put("all", websiteAll);
        TargetSocial targetSocial = new TargetSocial();
        Long socialUserAll = targetSocialService.queryCount(targetSocial);
        targetSocial.setUserFlag("0");
        Long socialUserPositive = targetSocialService.queryCount(targetSocial);
        JSONObject targetSocialResult = new JSONObject();
        targetSocialResult.put("positive", socialUserPositive);
        targetSocialResult.put("all", socialUserAll);
        Task singleSiteTask = new Task();
        singleSiteTask.setTaskType(0);
        Long singleTaskCount = taskService.queryCount(singleSiteTask);
        JSONObject taskSingleResult = new JSONObject();
        taskSingleResult.put("positive", singleTaskCount);
        taskSingleResult.put("all", singleTaskCount);
        Task commonTask = new Task();
        commonTask.setTaskType(1);
        Long commonTaskAll = taskService.queryCount(commonTask);
        commonTask.setEnableFlag("1");
        Long commonTaskPositive = taskService.queryCount(commonTask);
        JSONObject taskCommonResult = new JSONObject();
        taskCommonResult.put("positive", commonTaskPositive);
        taskCommonResult.put("all", commonTaskAll);
        Long logAll = logService.getAllCount();
        Long logPositive = logService.getSuccessCount();
        JSONObject logResult = new JSONObject();
        logResult.put("positive", logPositive);
        logResult.put("all", logAll);
        JSONObject result = new JSONObject();
        result.put("server", serverResult);
        result.put("project", projectResult);
        result.put("targetWebsite", targetWebsiteResult);
        result.put("targetSocial", targetSocialResult);
        result.put("taskCommon", taskCommonResult);
        result.put("taskSingle", taskSingleResult);
        result.put("log", logResult);
        return result;
    }

    public JSONObject getSingleItemCountGroupByDate(String params) {
        JSONObject paramsObj = JSONObject.parseObject(params);
        JSONObject result = new JSONObject();
        Date startDate = new Date(new Date().getTime() - 7 * ONE_DAY_SECONDS);
        Task exampleTask = new Task();
        if (paramsObj.containsKey("systemFlag")) exampleTask.setSystemFlag(paramsObj.getString("systemFlag"));
        if (paramsObj.containsKey("project")) exampleTask.setProject(paramsObj.getString("project"));
        if (paramsObj.containsKey("taskType")) exampleTask.setTaskType(paramsObj.getInteger("taskType"));
        Example<Task> example = Example.of(exampleTask);
        List<Task> targetTasks = taskRepository.findAll(example);
        List<String> taskIds = new ArrayList<>();
        targetTasks.forEach(t -> taskIds.add(t.getId().toString()));
        List<Object[]> itemsCounts = logRepository.queryItemCountGroupByDate(startDate, taskIds);
        result.putAll(paramsObj);
        result.put("counts", itemsCounts);
        return result;
    }

    public JSONArray getItemCountGroupByDate(String params) {
        JSONArray itemCounts = new JSONArray();
        itemCounts.add(getSingleItemCountGroupByDate(params));
        return itemCounts;
    }

    public JSONArray getItemCountGroupByDate() {
        JSONArray itemCounts = new JSONArray();
        List<MetaDict> systemFlags = metaDictService.queryDictByColumn("systemFlag");
        JSONObject paramsObj = new JSONObject();
        itemCounts.add(getSingleItemCountGroupByDate(paramsObj.toJSONString()));
        paramsObj.put("project", websiteSpiderName);
        itemCounts.add(getSingleItemCountGroupByDate(paramsObj.toJSONString()));
        systemFlags.forEach(sf -> {
            paramsObj.clear();
            paramsObj.put("systemFlag", sf.getDictCode());
            paramsObj.put("project", websiteSpiderName);
//            paramsObj.put("taskType", 1);
            itemCounts.add(getSingleItemCountGroupByDate(paramsObj.toJSONString()));
        });
        return itemCounts;
    }

    public List<List<Object[]>> getItemCountGroupByTask(Date startTime, Date endTime) {
        List<List<Object[]>> resultsList = new ArrayList<>();
        List<Object[]> projectResultsList = new ArrayList<>();
        List<Object[]> spiderResultsList = new ArrayList<>();
        List<Object[]> itemsCounts;
        itemsCounts = logRepository.queryItemCountGroupByAllTask(startTime, endTime);
        int i = 0;
        Map<String, Long> projectCountMap = new HashMap<>();
        for (Object[] itemCount : itemsCounts) {
            if (i < itemsCounts.size() && i >= 15) {
                break;
            }
            Integer taskId = (Integer) itemCount[0];
            Optional<Task> taskOptional = taskRepository.findById(taskId);
            if (taskOptional.isPresent()) {
                Task task = taskOptional.get();
                String projectName = task.getProject();
                if (projectCountMap.containsKey(projectName)) {
                    projectCountMap.put(projectName, projectCountMap.get(projectName) + Long.parseLong(itemCount[1].toString()));
                } else {
                    projectCountMap.put(projectName, Long.parseLong(itemCount[1].toString()));
                }
                if (!task.getCarrierType().equals("2")) {
                    spiderResultsList.add(new Object[]{task.getName(), itemCount[1]});
                    i++;
                }
            }
        }
        int otherCounts = 0;
        while (i < itemsCounts.size()) {
            Object[] itemCount = itemsCounts.get(i);
            Integer taskId = (Integer) itemCount[0];
            Optional<Task> taskOptional = taskRepository.findById(taskId);
            if (taskOptional.isPresent()) {
                otherCounts += Integer.parseInt(itemCount[1].toString());
                String projectName = taskOptional.get().getProject();
                if (projectCountMap.containsKey(projectName)) {
                    projectCountMap.put(projectName, projectCountMap.get(projectName) + Long.parseLong(itemCount[1].toString()));
                } else {
                    projectCountMap.put(projectName, Long.parseLong(itemCount[1].toString()));
                }
            }
            i++;
        }
        spiderResultsList.add(new Object[]{"其他任务", otherCounts});
        projectCountMap.keySet().forEach(key -> projectResultsList.add(new Object[]{key, projectCountMap.get(key)}));
        resultsList.add(projectResultsList);
        resultsList.add(spiderResultsList);
        return resultsList;
    }
}
