package com.yizhi.application.report.research;

import com.yizhi.application.report.research.vo.ReportResearchAnalyze;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.core.application.context.TaskContext;
import com.yizhi.core.application.file.constant.FileConstant;
import com.yizhi.core.application.file.task.AbstractDefaultTask;
import com.yizhi.core.application.file.util.OssUpload;
import com.yizhi.research.application.feign.ResearchAnswerClient;
import com.yizhi.research.application.feign.ResearchQuestionClient;
import com.yizhi.research.application.feign.ResearchQuestionOptionClient;
import com.yizhi.research.application.feign.ResearchReportClient;
import com.yizhi.research.application.vo.api.ViewAnswerQuestionOptionVo;
import com.yizhi.research.application.vo.api.ViewAnswerQuestionVo;
import com.yizhi.research.application.vo.api.ViewAnswerVo;
import com.yizhi.research.application.vo.domain.ResearchVo;
import com.yizhi.research.application.vo.domain.StatisticsResearchVo;
import com.yizhi.research.application.vo.domain.TrResearchQuestionOptionVo;
import com.yizhi.research.application.vo.domain.TrResearchQuestionVo;
import com.yizhi.statistics.application.entity.StatisticsResearch;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static java.math.BigDecimal.ROUND_HALF_DOWN;

@Component
public class DownloadResearchAnalyze extends AbstractDefaultTask<String, Map<String, Object>> {

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

    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

    @Autowired
    private ResearchAnswerClient researchAnswerClient;

    @Autowired
    private ResearchReportClient researchReportClient;

    @Autowired
    private ResearchQuestionOptionClient researchQuestionOptionClient;
    @Autowired
    private ResearchQuestionClient researchQuestionClient;

    @Override
    protected String execute(Map<String, Object> map) {

        ResearchVo research = (ResearchVo) map.get("research");
        RequestContext context = (RequestContext) map.get("context");
        String startDate = (String) map.get("startDate");
        String endDate = (String) map.get("endDate");
        String orgNameorOrgCode = (String) map.get("orgNameorOrgCode");
        String accountName = (String) map.get("accountName");
        Integer joinState = (Integer) map.get("joinState");
        String taskName = (String) map.get("taskName");
        Long taskId = (Long) map.get("taskId");
        String serialNo = (String) map.get("serialNo");

        Date submitTime = new Date();
        TaskContext taskContext = new TaskContext(taskId, serialNo, taskName, context.getAccountId(), submitTime, context.getSiteId(), context.getCompanyId());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        working(taskContext);

        Integer pageNo = 1;
        Integer pageSize = 20;
        List<ViewAnswerVo> viewAnswerVos = new ArrayList<ViewAnswerVo>();
        List<ViewAnswerVo> viewAnswerVos1;
        List<TrResearchQuestionOptionVo> trResearchQuestionOptions = researchQuestionOptionClient.listOption(research.getId());
        List<TrResearchQuestionVo> trResearchQuestions = researchQuestionClient.listAll(research.getId());
        if (trResearchQuestions == null) {
            trResearchQuestions = new ArrayList<TrResearchQuestionVo>();
        }

        if (trResearchQuestionOptions == null) {
            trResearchQuestionOptions = new ArrayList<TrResearchQuestionOptionVo>();
        }
        Integer total = researchAnswerClient.viewAnswersCount(research.getId());
        int pageCount = (int) Math.ceil(Double.valueOf(total) / pageSize);
        for (int i = 0; i < pageCount; i++) {
            viewAnswerVos1 = researchAnswerClient.viewAnswersList(research.getId(), pageNo, pageSize);
            viewAnswerVos.addAll(viewAnswerVos1);
            pageNo++;
        }

        pageNo = 1;
        pageSize = 20;
        Integer pageTotal = researchReportClient.researchViewCount(startDate, endDate, research.getId(), orgNameorOrgCode, accountName, joinState);
        pageCount = (int) Math.ceil(Double.valueOf(pageTotal) / pageSize);
        List<StatisticsResearchVo> statisticsResearches = new ArrayList<>();
        List<StatisticsResearchVo> listOne;
        for (int i = 0; i < pageCount; i++) {
            listOne = researchReportClient.researchViews(startDate, endDate, research.getId(), orgNameorOrgCode, accountName, joinState, pageNo, pageSize);
            statisticsResearches.addAll(listOne);
            pageNo++;
        }
        ReportResearchAnalyze reportResearchAnalyze = (ReportResearchAnalyze) map.get("reportResearchAnalyze");
        StatisticsResearchVo join = researchReportClient.getCanStateCount(startDate, endDate, research.getId(), orgNameorOrgCode, accountName, joinState);
        reportResearchAnalyze.setJoinCount(join.getCanStateCount());
        reportResearchAnalyze.setRealJoinCount(join.getJoinStateCount());
        reportResearchAnalyze.setSubmitCount(join.getJoinStateCount());
        reportResearchAnalyze.setQuestionCount(trResearchQuestions.size());


        String upLoadUrl = null;
        String requestPath = FileConstant.SAVE_PATH;
//        String requestPath = "/Users/dingxiaowei/aaa";
        //String requestPath= "E\\";
        File fileDir = new File(requestPath);
        if (!fileDir.exists()) {
            fileDir.mkdir();
        }

        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建单元格格式
        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.LEFT);//创建居左格式
        Cell cell;

        HSSFSheet sheet = workbook.createSheet(research.getName() + "_" + sdf.format(submitTime));
        //创建第一行
        HSSFRow row = sheet.createRow((int) 0);
        cell = row.createCell((short) 0);
        cell.setCellValue(research.getName());
        //创建第二行
        row = sheet.createRow((int) 1);
        cell = row.createCell((short) 0);
        cell.setCellValue("统计周期:" + startDate + "～" + endDate);


        //创建第三行
        row = sheet.createRow((int) 2);
        cell = row.createCell((short) 0);
        if (reportResearchAnalyze.getQuestionCount() != null) {
            cell.setCellValue("题目总数:" + reportResearchAnalyze.getQuestionCount());
        }
        cell = row.createCell((short) 1);
        if (reportResearchAnalyze.getSubmitCount() != null) {
            cell.setCellValue("提交问卷份数:" + reportResearchAnalyze.getSubmitCount());
        }
        cell = row.createCell((short) 2);
        if (reportResearchAnalyze.getJoinCount() != null) {
            cell.setCellValue("可参加人数:" + reportResearchAnalyze.getJoinCount());
        }
        cell = row.createCell((short) 3);
        if (reportResearchAnalyze.getRealJoinCount() != null) {
            cell.setCellValue("实际参加人数：" + reportResearchAnalyze.getRealJoinCount());
        }
        try {
            Map<Long, StatisticsResearchVo> statisticsResearchMap = new HashMap<Long, StatisticsResearchVo>();
            for (StatisticsResearchVo statisticsResearch : statisticsResearches) {
                if (statisticsResearch == null) {
                    continue;
                }
                statisticsResearchMap.put(statisticsResearch.getAccountId(), statisticsResearch);
            }
            int index = 3;

            List<ViewAnswerQuestionVo> answerQuestions;
            List<ViewAnswerQuestionOptionVo> viewAnswerQuestionOptionVos;

            Map<Long, Integer> viewAnswerVoMap = new HashMap<Long, Integer>();
            Map<Long, List<ViewAnswerQuestionVo>> accountMap = new HashMap<Long, List<ViewAnswerQuestionVo>>();
            List<ViewAnswerQuestionVo> voList = new ArrayList<ViewAnswerQuestionVo>();
            Map<Long, Integer> viewAnswerQuestionOptionVoMap = new HashMap<Long, Integer>();
            Map<Long, ViewAnswerQuestionOptionVo> optionVoMap = new HashMap<Long, ViewAnswerQuestionOptionVo>();
            Long questionId;
            Long accountId;
            StatisticsResearchVo statisticsResearch;
            ViewAnswerQuestionOptionVo questionOptionVo;
            for (ViewAnswerVo viewAnswerVo : viewAnswerVos) {
                statisticsResearch = statisticsResearchMap.get(viewAnswerVo.getAccountId());
                if (statisticsResearch == null) {
                    continue;
                }
                answerQuestions = viewAnswerVo.getAnswerQuestions();
                if (answerQuestions == null) {
                    continue;
                }
                for (ViewAnswerQuestionVo viewAnswerQuestionVo : answerQuestions) {
                    questionId = viewAnswerQuestionVo.getId();
                    Integer validCount = 0;//表示该问题有效填写的个数
                    boolean preCheck = false;
                    if (viewAnswerQuestionVo.getType() == 3) {//问答题
                        viewAnswerQuestionVo.setAccountId(viewAnswerVo.getAccountId());
                        if (viewAnswerQuestionVo.getAnswerContent() != null) {
                            voList.add(viewAnswerQuestionVo);
                            accountMap.put(questionId, voList);
                            preCheck = true;
                            // viewAnswerQuestionOptionVo.setCheckedCount(checkCount);
                        }
                    } else {
                        viewAnswerQuestionOptionVos = viewAnswerQuestionVo.getOptions();
                        for (ViewAnswerQuestionOptionVo viewAnswerQuestionOptionVo : viewAnswerQuestionOptionVos) {
                            Integer count;
                            //单选题或者多选题
                            if (viewAnswerQuestionVo.getType() == 1 || viewAnswerQuestionVo.getType() == 2) {
                                if (viewAnswerQuestionOptionVo.getAnswerChecked()) {
                                    preCheck = true;
                                    count = viewAnswerQuestionOptionVoMap.get(viewAnswerQuestionOptionVo.getId());
                                    if (count == null) {
                                        count = 1;
                                    } else {
                                        count++;
                                    }
                                    viewAnswerQuestionOptionVoMap.put(viewAnswerQuestionOptionVo.getId(), count);
                                    //viewAnswerQuestionOptionVo.setCheckedCount(checkCount);
                                }
                            } else {//打分题
                                Integer answerScore = viewAnswerQuestionOptionVo.getAnswerScore();
                                Integer totalSocre;
                                if (answerScore != null) {
                                    preCheck = true;
                                    questionOptionVo = optionVoMap.get(viewAnswerQuestionOptionVo.getId());
                                    if (questionOptionVo == null) {
                                        questionOptionVo = new ViewAnswerQuestionOptionVo();
                                        questionOptionVo.setAnswerScore(answerScore);
                                        questionOptionVo.setCheckCount(1);
                                        questionOptionVo.setMinScore(answerScore);
                                        questionOptionVo.setMaxScore(answerScore);
                                        questionOptionVo.setTotalSocre(answerScore);
                                        optionVoMap.put(viewAnswerQuestionOptionVo.getId(), questionOptionVo);
                                    } else {
                                        count = questionOptionVo.getCheckCount();
                                        questionOptionVo.setCheckCount(++count);
                                        if (answerScore > questionOptionVo.getMaxScore()) {
                                            questionOptionVo.setMaxScore(answerScore);
                                        }
                                        if (answerScore < questionOptionVo.getMinScore()) {
                                            questionOptionVo.setMinScore(answerScore);
                                        }
                                        totalSocre = questionOptionVo.getTotalSocre();
                                        totalSocre += answerScore;
                                        questionOptionVo.setTotalSocre(totalSocre);
                                    }
                                }
                            }
                        }
                    }
                    if (preCheck) {
                        validCount = viewAnswerVoMap.get(questionId);
                        if (validCount == null) {
                            validCount = 1;
                        } else {
                            validCount += 1;
                        }
                        viewAnswerVoMap.put(questionId, validCount);
                    }

                }

            }
            List<TrResearchQuestionOptionVo> optionList;
            Map<Long, List<TrResearchQuestionOptionVo>> optionMap = new HashMap<Long, List<TrResearchQuestionOptionVo>>();
            Long questionsId;
            for (TrResearchQuestionOptionVo trResearchQuestionOption : trResearchQuestionOptions) {
                questionsId = trResearchQuestionOption.getQuestionId();
                optionList = optionMap.get(questionsId);
                if (optionList != null) {
                    optionList.add(trResearchQuestionOption);
                } else {
                    optionList = new ArrayList<TrResearchQuestionOptionVo>();
                    optionList.add(trResearchQuestionOption);
                }
                optionMap.put(questionsId, optionList);
            }
            //答卷的问题
            BigDecimal d;
            BigDecimal dou;
            BigDecimal b = new BigDecimal(100);
            int s = 0;
            for (TrResearchQuestionVo trResearchQuestion : trResearchQuestions) {
                row = sheet.createRow((int) index);
                index++;
                cell = row.createCell((short) 0);
                if (trResearchQuestion.getContent() != null && trResearchQuestion.getNo() != null && trResearchQuestion.getType() == 1) {
                    cell.setCellValue(trResearchQuestion.getNo() + "、" + "(单选题)" + trResearchQuestion.getContent());
                }
                if (trResearchQuestion.getContent() != null && trResearchQuestion.getNo() != null && trResearchQuestion.getType() == 2) {
                    cell.setCellValue(trResearchQuestion.getNo() + "、" + "(多选题)" + trResearchQuestion.getContent());
                }
                if (trResearchQuestion.getContent() != null && trResearchQuestion.getNo() != null && trResearchQuestion.getType() == 3) {
                    cell.setCellValue(trResearchQuestion.getNo() + "、" + "(问答题)" + trResearchQuestion.getContent());
                }
                if (trResearchQuestion.getContent() != null && trResearchQuestion.getNo() != null && trResearchQuestion.getType() == 4) {
                    cell.setCellValue(trResearchQuestion.getNo() + "、" + "(打分题)" + trResearchQuestion.getContent());
                }
                questionId = trResearchQuestion.getId();
                Integer valid = viewAnswerVoMap.get(questionId);
                if (valid == null) {
                    valid = 0;
                }
                //单选
                if (trResearchQuestion.getType() == 1 || trResearchQuestion.getType() == 2) {
                    row.createCell((short) 1).setCellValue("有效填写:" + valid);
                    row = sheet.createRow((int) index);
                    index++;
                    row.createCell((short) 0).setCellValue("选项");
                    row.createCell((short) 1).setCellValue("小计");
                    row.createCell((short) 2).setCellValue("比例");
                    optionList = optionMap.get(questionId);
                    Integer totalCount = 0;
                    if (optionList != null) {
                        for (TrResearchQuestionOptionVo trResearchQuestionOption : optionList) {
                            Integer i = viewAnswerQuestionOptionVoMap.get(trResearchQuestionOption.getId());
                            if (i == null) {
                                i = 0;
                            }
                            totalCount += i;
                        }
                        for (TrResearchQuestionOptionVo trResearchQuestionOption : optionList) {
                            Integer i = viewAnswerQuestionOptionVoMap.get(trResearchQuestionOption.getId());
                            if (i == null) {
                                i = 0;
                            }
                            row = sheet.createRow((int) index);
                            index++;
                            cell = row.createCell((short) 0);
                            if (trResearchQuestionOption.getContent() != null) {
                                cell.setCellValue(trResearchQuestionOption.getContent());
                            }
                            row.createCell((short) 1).setCellValue(i);
                            d = new BigDecimal((double) i).multiply(b);
                            dou = new BigDecimal((double) totalCount);
                            cell = row.createCell((short) 2);
                            if (d.compareTo(BigDecimal.ZERO) == 0 || dou.compareTo(BigDecimal.ZERO) == 0) {
                                cell.setCellValue("0%");
                            } else {
                                cell.setCellValue(d.divide(dou, 0, ROUND_HALF_DOWN) + "%");
                            }
                        }
                    }
                    //问答题
                } else if (trResearchQuestion.getType() == 3) {
                    voList = accountMap.get(questionId);
                    if (voList == null) {
                        continue;
                    }
                    for (ViewAnswerQuestionVo viewAnswerQuestionVo : voList) {
                        int i = 0;
                        accountId = viewAnswerQuestionVo.getAccountId();
                        statisticsResearch = statisticsResearchMap.get(accountId);
                        row = sheet.createRow((int) index);
                        index++;
                        cell = row.createCell((short) 0);
                        if (statisticsResearch.getAccountName() != null) {
                            cell.setCellValue(statisticsResearch.getAccountName());
                        }
                        cell = row.createCell((short) 1);
                        if (statisticsResearch.getFinishTime() != null) {
                            cell.setCellValue(sdf.format(statisticsResearch.getFinishTime()));
                        }
                        cell = row.createCell((short) 2);
                        if (viewAnswerQuestionVo.getAnswerContent() != null) {
                            cell.setCellValue(viewAnswerQuestionVo.getAnswerContent());
                        }
                    }
                } else {
                    //打分题
                    row.createCell((short) 1).setCellValue("有效填写:" + valid);
                    row = sheet.createRow((int) index);
                    index++;
                    row.createCell((short) 0).setCellValue("打分项");
                    row.createCell((short) 1).setCellValue("10");
                    row.createCell((short) 2).setCellValue("9");
                    row.createCell((short) 3).setCellValue("8");
                    row.createCell((short) 4).setCellValue("7");
                    row.createCell((short) 5).setCellValue("6");
                    row.createCell((short) 6).setCellValue("5");
                    row.createCell((short) 7).setCellValue("4");
                    row.createCell((short) 8).setCellValue("3");
                    row.createCell((short) 9).setCellValue("2");
                    row.createCell((short) 10).setCellValue("1");
                    row.createCell((short) 11).setCellValue("0");
                    row.createCell((short) 12).setCellValue("参与人数");
                    row.createCell((short) 13).setCellValue("最高分");
                    row.createCell((short) 14).setCellValue("最低分");
                    row.createCell((short) 15).setCellValue("总分");
                    row.createCell((short) 16).setCellValue("平均分");
                    if (trResearchQuestionOptions == null) {
                        continue;
                    }
                    for (TrResearchQuestionOptionVo trResearchQuestionOption : trResearchQuestionOptions) {
                        questionOptionVo = optionVoMap.get(trResearchQuestionOption.getId());
                        if (questionOptionVo == null) {
                            continue;
                        }
                        int i = questionOptionVo.getAnswerScore();
                        row = sheet.createRow(index);
                        index++;
                        cell = row.createCell((short) 0);
                        if (trResearchQuestionOption.getContent() != null) {
                            cell.setCellValue(trResearchQuestionOption.getContent());
                        }
                        for (int j = 0; j < 11; j++) {
                            row.createCell((short) (11 - j));
                            if (i == j) {
                                cell = row.getCell((short) (11 - j));
                                if (questionOptionVo.getCheckCount() != null) {
                                    cell.setCellValue(questionOptionVo.getCheckCount());
                                }
                            }
                        }
                        d = new BigDecimal(questionOptionVo.getTotalSocre());
                        dou = new BigDecimal(questionOptionVo.getCheckCount());
                        cell = row.createCell((short) 12);
                        if (questionOptionVo.getCheckCount() != null) {
                            cell.setCellValue(questionOptionVo.getCheckCount());
                        }
                        cell = row.createCell((short) 13);
                        if (questionOptionVo.getMaxScore() != null) {
                            cell.setCellValue(questionOptionVo.getMaxScore());
                        }
                        cell = row.createCell((short) 14);
                        if (questionOptionVo.getMinScore() != null) {
                            cell.setCellValue(questionOptionVo.getMinScore());
                        }
                        cell = row.createCell((short) 15);
                        if (questionOptionVo.getTotalSocre() != null) {
                            cell.setCellValue(questionOptionVo.getTotalSocre());
                        }
                        cell = row.createCell((short) 16);
                        if (d.compareTo(BigDecimal.ZERO) == 0 || dou.compareTo(BigDecimal.ZERO) == 0) {
                            cell.setCellValue("0");
                        } else {
                            cell.setCellValue(d.divide(dou, 2, ROUND_HALF_DOWN) + "");
                        }
                    }
                }
                s++;
//                taskDetail(taskContext.getTaskId(), research.getName() + "导出数据第" + s + "行成功");
            }

            //导出

            StringBuffer fileNameSb = new StringBuffer().append(research.getName() + "分析统计_" + sdf.format(submitTime)).append(".xls");
            String fileName = fileNameSb.toString();
            String path = new StringBuffer().append(requestPath).append(fileNameSb).toString();
            FileOutputStream os = null;
            File file = null;
            try {
                os = new FileOutputStream(path);
                workbook.write(os);
                //阿里云返回url
                upLoadUrl = OssUpload.upload(path, fileName);
                file = new File(path);
                success(taskContext, "成功", upLoadUrl);
            } catch (Exception e1) {
                e1.printStackTrace();
                fail(taskContext, "写入过程中发生错误");
                logger.error("写入数据到Excel的过程中或者上传到阿里云中发生错误");
            } finally {
                if (os != null) {
                    os.close();
                }
                if (workbook != null) {
                    workbook.close();
                }
                if (file != null) {
                    file.delete();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail(taskContext, research.getName() + "导出过程中发生错误，请查看日志");
            logger.error("创建Excel的过程中发生错误");
        }
        return upLoadUrl;
    }
}

