package com.mooctest.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mooctest.dao.FinalReportDao;
import com.mooctest.data.BugDTO;
import com.mooctest.data.FinalReportDTO;
import com.mooctest.data.TaskDTO;
import com.mooctest.model.Bug;
import com.mooctest.model.FinalReport;
import com.mooctest.util.HttpUtil;
import com.mooctest.util.ReportUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class FinalReportService {

    @Autowired
    FinalReportDao finalReportDao;

    @Value("${report.export.addr}")
    String reportExportAddr;

    public FinalReportDTO save(FinalReportDTO dto) {

        FinalReport finalReport = new FinalReport();
        BeanUtils.copyProperties(dto, finalReport);
        finalReport.setImgUrls(String.join(",", dto.getImgUrls()));
        finalReport.setCreateTime(new Date());
        finalReport = finalReportDao.save(finalReport);
        BeanUtils.copyProperties(finalReport, dto);
        return dto;
    }

    public FinalReportDTO update(long reportId, FinalReportDTO dto) {
        FinalReport report = finalReportDao.findOne(reportId);
        dto.setCreateTime(report.getCreateTime());
        BeanUtils.copyProperties(dto, report);
        report.setImgUrls(String.join(",", dto.getImgUrls()));
        finalReportDao.save(report);

        return dto;
    }

    public List<FinalReportDTO> getByExamIdAndCaseId(long examId, long caseId) {
        List<FinalReport> frs = finalReportDao.findByExamIdAndCaseId(examId, caseId);
        return wrap(frs);
    }

    public List<FinalReportDTO> getBySourceId(String sourceId) {
        List<FinalReport> frs = finalReportDao.findBySourceId(sourceId);
        return wrap(frs);
    }

    private List<FinalReportDTO> wrap(List<FinalReport> frs) {
        return frs.stream().map(finalReport -> {
            FinalReportDTO dto = new FinalReportDTO();
            BeanUtils.copyProperties(finalReport, dto);
            dto.setImgUrls(finalReport.getImgUrls().split(","));
            return dto;
        }).collect(Collectors.toList());
    }

    public void delete(long reportId) {
        finalReportDao.delete(reportId);
    }

    public String getExportReportAddr(TaskDTO task) {
        List<FinalReport> finalReports = finalReportDao.findByExamIdAndCaseId(task.getExamId(), task.getCaseId());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

        JSONObject reportJson = genJsonForExport(task, finalReports);
        HttpEntity<String> request = new HttpEntity<>(reportJson.toJSONString(), headers);
        RestTemplate rt = HttpUtil.getRestTemplate();

        String url = rt.postForObject(reportExportAddr, request, String.class);
        return url;
    }

    private JSONObject genJsonForExport(TaskDTO task, List<FinalReport> finalReports) {
        JSONObject root = new JSONObject();
        JSONArray projects = new JSONArray();
        JSONObject project = new JSONObject();

        project.put("projectId", task.getExamId() + "-" +task.getCaseId());
        project.put("icon", task.getIcon());
        project.put("name", task.getName());
        project.put("version", task.getVersion());
        project.put("startTime", task.getStartTime());
        project.put("endTime", task.getEndTime());
        project.put("reports", finalReports);
        projects.add(project);
        root.put("projects", projects);
        root.put("menus", new JSONArray().fluentAdd("众包测试报告"));

        JSONObject projectStatistics = new JSONObject();
        projectStatistics.put("categorys", genAttrArray(ReportUtil.category2String));
        projectStatistics.put("severity", genAttrArray(ReportUtil.severity2String));
        projectStatistics.put("recurrent", genAttrArray(ReportUtil.recurrent2String));
        root.put("projectStatistics", projectStatistics);
        return root;
    }

    private JSONArray genAttrArray(Map map) {
        JSONArray arr = new JSONArray();
        map.forEach((k, v) -> {
            JSONObject obj = new JSONObject();
            obj.put("name", v);
            obj.put("value", k);
            arr.add(obj);
        });
        return arr;
    }

    public void transAllBug2FinalReport(List<BugDTO> bugs, long examId, long caseId) {
        List<FinalReport> finalReports = bugs.parallelStream().map(bug -> {
            FinalReport finalReport = new FinalReport();
            finalReport.setDescription(bug.getDescription());
            finalReport.setImgUrls(String.join(",", bug.getImgUrls()));
            finalReport.setSeverity(bug.getSeverity());
            finalReport.setRecurrent(bug.getRecurrent());
            Integer category = ReportUtil.string2Category.get(bug.getBugCategory());
            if (category == null) {
                category = 7;
            }
            finalReport.setCategory(category);
            finalReport.setCreateTime(new Date());
            finalReport.setWriterId(1);
            finalReport.setExamId(examId);
            finalReport.setCaseId(caseId);
            return finalReport;
        }).collect(Collectors.toList());

        finalReportDao.save(finalReports);
    }


}
