package com.microservices.dss.makerspace.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.dss.enums.DssTaskStatus;
import com.microservices.dss.makerspace.domain.vo.MakerSpaceTotalDataVo;
import com.microservices.dss.makerspace.domain.vo.TaskHeatInfoVo;
import com.microservices.dss.makerspace.mapper.TasksMapper;
import com.microservices.dss.makerspace.service.ITasksService;
import com.microservices.dss.projects.domain.PieChartNameAndValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.List;
import java.util.Map;

import static com.microservices.dss.utils.DataStructureConvertUtil.MapInitByMonth;
import static com.microservices.dss.utils.DataStructureConvertUtil.dbResult2Array;
import static com.microservices.dss.utils.DateUtil.getFormattedCurrentDateTime;
import static com.microservices.dss.utils.DateUtil.getFormattedPreviousYearSameMonth;

@Service
public class TasksServiceImpl implements ITasksService {

    private static final Logger logger = LoggerFactory.getLogger(TasksServiceImpl.class);

    @Resource
    private TasksMapper tasksMapper;

    @Override
    public MakerSpaceTotalDataVo getTotalStatisticalData() {
        MakerSpaceTotalDataVo makerSpaceTotalDataVo = new MakerSpaceTotalDataVo();
        makerSpaceTotalDataVo.setTotalTasks(tasksMapper.getTotalTaskCount());
        makerSpaceTotalDataVo.setTotalApplicants(tasksMapper.getTotalApplicantCount());
        makerSpaceTotalDataVo.setCurrentTotalAwardAmount(tasksMapper.getCurrentTotalAwardAmount()/10000);
        makerSpaceTotalDataVo.setTaskPublishedCountsByYear(tasksMapper.getTaskPublishedCountsByYear());
        makerSpaceTotalDataVo.setTaskBountyCountsByYear(tasksMapper.getTaskBountyCountsByYear());
        return makerSpaceTotalDataVo;
    }

    @Override
    public int[] getTaskAdditionTrendData() {
        String startTime = getFormattedPreviousYearSameMonth();
        String endTime = getFormattedCurrentDateTime();
        try {
            return getNewAddedTasksByMonth(startTime, endTime);
        } catch (ParseException e) {
            logger.error("ParseException occurred while getting task addition trend data", e);
            throw new ServiceException("获取新增任务趋势数据失败");
        } catch (JsonProcessingException e) {
            logger.error("JsonProcessingException occurred while getting task addition trend data", e);
            throw new ServiceException("获取新增任务趋势数据失败");
        }
    }

    @Override
    public int[] getPaperAdditionTrendData() {
        String startTime = getFormattedPreviousYearSameMonth();
        String endTime = getFormattedCurrentDateTime();
        try {
            return getNewAddedPapersByMonth(startTime, endTime);
        } catch (ParseException e) {
            logger.error("ParseException occurred while getting paper addition trend data", e);
            throw new ServiceException("获取新增成果趋势数据失败");
        } catch (JsonProcessingException e) {
            logger.error("JsonProcessingException occurred while getting paper addition trend data", e);
            throw new ServiceException("获取新增成果趋势数据失败");
        }
    }

    @Override
    public List<Map<String, String>> getTaskOperLogTopN(Integer topNum) {
        return tasksMapper.getTaskOperLogTopN(topNum);
    }

    @Override
    public List<PieChartNameAndValue> getOpeningTaskStatusDistribution(Integer topNum) {
        List<PieChartNameAndValue>  distribution = tasksMapper.getOpeningTaskNumOfTaskStatus(topNum);
        for (PieChartNameAndValue pieChartNameAndValue : distribution) {
            DssTaskStatus status = DssTaskStatus.values()[Integer.parseInt(pieChartNameAndValue.getName())];
            pieChartNameAndValue.setName(status.getName());
        }
        return distribution;
    }

    @Override
    public List<PieChartNameAndValue> getAllTaskCategoryDistribution() {
        return tasksMapper.getAllTaskNumOfTaskCategory();
    }

    @Override
    public List<Map<String, String>> getBountyDistribution() {
        List<Map<String, String>> bountyDistribution = tasksMapper.getBountyDistribution();
        Map<String, String> totalCompletedBounty = tasksMapper.getTotalCompletedBounty();
        bountyDistribution.add(totalCompletedBounty);
        return bountyDistribution;
    }

    @Override
    public List<TaskHeatInfoVo> getTaskHeatTopN(Integer topNum) {

        return tasksMapper.getTaskInfoByVisits(topNum);
    }

    @Override
    public List<Map<String, String>> getTaskModeStatisticalData() {
        return tasksMapper.getTaskModeStatistic();
    }

    private int[] getNewAddedTasksByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException {
        int monthDiff = 12;
        Map<Object, Object> map_init = MapInitByMonth(monthDiff,endTime);
        List<Object> Db_result = tasksMapper.getNewAddedTasksByMonth(startTime, endTime);
        int[] resultArray = new int[monthDiff+1];
        return dbResult2Array(Db_result,"createTime","num",map_init,resultArray);
    }

    private int[] getNewAddedPapersByMonth(String startTime, String endTime) throws ParseException, JsonProcessingException {
        int monthDiff = 12;
        Map<Object, Object> map_init = MapInitByMonth(monthDiff,endTime);
        List<Object> Db_result = tasksMapper.getNewAddedPapersByMonth(startTime, endTime);
        int[] resultArray = new int[monthDiff+1];
        return dbResult2Array(Db_result,"createTime","num",map_init,resultArray);
    }
}
