package com.yizhi.application.report.research;

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.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.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
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.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

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

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

    @Autowired
    private ResearchAnswerClient researchAnswerClient;
    @Autowired
    private ResearchReportClient researchReportClient;

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

    @Override
    protected String execute(Map<String, Object> map) {
        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();
        }

        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");
        String serialNo = (String) map.get("serialNo");
        Long taskId = (Long) map.get("taskId");

        Date submitTime = new Date();
        Long accountId = context.getAccountId();
        TaskContext taskContext = new TaskContext(taskId, serialNo, taskName, accountId, submitTime, context.getSiteId(), context.getCompanyId());
        working(taskContext);
        Integer pageNo = 1;
        Integer pageSize = 20;
        List<ViewAnswerVo> viewAnswerVos = new ArrayList<ViewAnswerVo>();
        List<ViewAnswerVo> viewAnswerVos1;

        List<StatisticsResearchVo> statisticsResearches = null;
        String researchName = null;
        try {
            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);
            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++;
            }
            researchName = research.getName();
        } catch (Exception e) {
            e.printStackTrace();
            fail(taskContext, research.getName() + "获取数据过程中出现错误，请查看日志");
            logger.error("获取数据过程中出现错误");
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            //excel生成：excel-sheet-row-cell
            HSSFWorkbook workbook = new HSSFWorkbook();
            //创建单元格格式
            HSSFCellStyle style = workbook.createCellStyle();
            style.setAlignment(HorizontalAlignment.LEFT);//创建居左格式
            HSSFSheet sheet = workbook.createSheet(researchName + "_" + dateFormat.format(submitTime));
            HSSFRow row;
            HSSFCell cell;

            row = sheet.createRow((int) 2);
            cell = row.createCell((short) 0);
            cell.setCellValue("用户名");
            cell = row.createCell((short) 1);
            cell.setCellValue("姓名");
            cell = row.createCell((short) 2);
            cell.setCellValue("提交时间");

            int cellSize = 2;
            int index = 3;
            List<TrResearchQuestionVo> trResearchQuestions = (List<TrResearchQuestionVo>) map.get("trResearchQuestion");
            cellSize += trResearchQuestions.size();
            List<TrResearchQuestionOptionVo> trResearchQuestionOptions;
            Map<Long, Integer> locationMap = new HashMap<Long, Integer>();
            Map<Long, Integer> optionLocationMap = new HashMap<Long, Integer>();
            for (TrResearchQuestionVo trResearchQuestion : trResearchQuestions) {
                cell = row.createCell((short) index);
                if (null != trResearchQuestion.getId()) {
                    locationMap.put(trResearchQuestion.getId(), index);
                }
                index++;
                if (trResearchQuestion.getContent() != null) {
                    cell.setCellValue(trResearchQuestion.getContent());
                }
                trResearchQuestionOptions = trResearchQuestion.getOptions();
                if (trResearchQuestionOptions == null) {
                    continue;
                }
                if (trResearchQuestion.getType() == 4) {
                    for (TrResearchQuestionOptionVo trResearchQuestionOption : trResearchQuestionOptions) {
                        cell = row.createCell((short) index);
                        if (trResearchQuestionOption.getContent() != null) {
                            cell.setCellValue(trResearchQuestionOption.getContent());
                        }
                        if (null != trResearchQuestionOption.getId()) {
                            optionLocationMap.put(trResearchQuestionOption.getId(), index);
                        }
                        index++;
                    }
                    cellSize += trResearchQuestionOptions.size();
                }

            }
            cell = row.createCell((short) cellSize + 1);
            cell.setCellValue("所在部门");

            // 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short,
            // 创建第1行
            row = sheet.createRow((int) 0);
            //合并单元格
            CellRangeAddress cra = new CellRangeAddress(0, 0, 0, cellSize); // 起始行, 终止行, 起始列, 终止列
            sheet.addMergedRegion(cra);
            //合并前6列当做第0行的第0列
            cell = row.createCell((short) 0);
            cell.setCellValue(researchName + "调研明细");
            cell.setCellStyle(style);


            //创建第2行
            row = sheet.createRow((int) 1);
            CellRangeAddress cra1 = new CellRangeAddress(1, 1, 0, cellSize); // 起始行, 终止行, 起始列, 终止列
            sheet.addMergedRegion(cra1);
            cell = row.createCell((short) 0);
            cell.setCellValue("统计周期:" + startDate + "～" + endDate);
            cell.setCellStyle(style);

            //答卷
            ViewAnswerVo viewAnswerVo;
            //答卷的问题
            ViewAnswerQuestionVo viewAnswerQuestionVo;
            //答卷下问题选项
            ViewAnswerQuestionOptionVo viewAnswerQuestionOptionVo;
            //这些实体的列表
            List<ViewAnswerQuestionVo> viewAnswerQuestionVos;
            List<ViewAnswerQuestionOptionVo> viewAnswerQuestionOptionVos;

            Map<Long, ViewAnswerVo> viewAnswerVoMap = new HashMap<Long, ViewAnswerVo>();
            String[] parentNames;
            Long questionId;
            Long optionId;
            int location;
            //通过accountId和提交的答案关联
            for (ViewAnswerVo viewAnswerVo1 : viewAnswerVos) {
                viewAnswerVoMap.put(viewAnswerVo1.getAccountId(), viewAnswerVo1);
            }
            int s = 0;
            //遍历中间表
            int i = 3;
            for (StatisticsResearchVo statisticsResearch : statisticsResearches) {
                viewAnswerVo = viewAnswerVoMap.get(statisticsResearch.getAccountId());
                if (statisticsResearch == null || viewAnswerVo == null) {
                    continue;
                } else {
                    row = sheet.createRow((short) i);
                    i++;
                }
                cell = row.createCell((short) 0);
                if (statisticsResearch.getAccountName() != null) {
                    cell.setCellValue(statisticsResearch.getAccountName());
                }
                cell = row.createCell((short) 1);
                if (statisticsResearch.getAccountFullName() != null) {
                    cell.setCellValue(statisticsResearch.getAccountFullName());
                }
                cell = row.createCell((short) 2);
                if (statisticsResearch.getFinishTime() != null) {
                    cell.setCellValue(format.format(statisticsResearch.getFinishTime()));
                }
                viewAnswerQuestionVos = viewAnswerVo.getAnswerQuestions();
                if (viewAnswerQuestionVos == null) {
                    continue;
                }
                //  查询考卷的问题
                for (int j = 0; j < viewAnswerQuestionVos.size(); j++) {
                    viewAnswerQuestionVo = viewAnswerQuestionVos.get(j);
                    questionId = viewAnswerQuestionVo.getId();
                    if (null != locationMap.get(questionId)) {
                        location = locationMap.get(questionId);
                    } else {
                        continue;
                    }

                    Integer num = null;
                    // 对获取的答卷的问题和答案进行组装
                    for (TrResearchQuestionVo question : trResearchQuestions) {
                        if (question.getId().equals(viewAnswerQuestionVo.getId())) {
                            if (num == null) {

                                num = question.getJumpNum();

                                if (viewAnswerQuestionVo.getType() == 4) {
                                    row.createCell((short) location);
                                }
                                if (viewAnswerQuestionVo.getType() == 3) {
                                    cell = row.createCell(location);
                                    if (viewAnswerQuestionVo.getAnswerContent() != null) {
                                        cell.setCellValue(viewAnswerQuestionVo.getAnswerContent());
                                    }
                                }
                                viewAnswerQuestionOptionVos = viewAnswerQuestionVo.getOptions();
                                if (viewAnswerQuestionOptionVos == null) {
                                    continue;
                                }
                                for (int k = 0; k < viewAnswerQuestionOptionVos.size(); k++) {
                                    viewAnswerQuestionOptionVo = viewAnswerQuestionOptionVos.get(k);
                                    if (viewAnswerQuestionVo.getType() == 1 && viewAnswerQuestionOptionVo.getAnswerChecked()) {
                                        cell = row.createCell((short) location);
                                        if (viewAnswerQuestionOptionVo.getContent() != null) {
                                            cell.setCellValue(viewAnswerQuestionOptionVo.getContent());
                                        }
                                        num = viewAnswerQuestionOptionVo.getJumpNum();
                                    } else if (viewAnswerQuestionVo.getType() == 2 && viewAnswerQuestionOptionVo.getAnswerChecked()) {
                                        if (row.getCell(location) != null) {
                                            cell = row.getCell(location);
                                            if (viewAnswerQuestionOptionVo.getContent() != null) {
                                                cell.setCellValue(cell.getStringCellValue() + "$$" + viewAnswerQuestionOptionVo.getContent());

                                            }
                                        } else {
                                            cell = row.createCell(location);
                                            if (viewAnswerQuestionOptionVo.getContent() != null) {
                                                cell.setCellValue(viewAnswerQuestionOptionVo.getContent());
                                            }
                                        }
                                    } else {
                                        optionId = viewAnswerQuestionOptionVo.getId();
                                        if (optionLocationMap.get(optionId) != null) {
                                            location = optionLocationMap.get(optionId);
                                        } else {
                                            continue;
                                        }
                                        cell = row.createCell(location);
                                        if (viewAnswerQuestionOptionVo.getAnswerScore() != null) {
                                            cell.setCellValue(viewAnswerQuestionOptionVo.getAnswerScore());
                                        }
                                    }

                                }
                                // 判断当前题目是不是上一题所跳的题
                            } else if (num != null && question.getNo().equals(num)) {
                                num = question.getJumpNum();

                                if (viewAnswerQuestionVo.getType() == 4) {
                                    row.createCell((short) location);
                                }
                                if (viewAnswerQuestionVo.getType() == 3) {
                                    cell = row.createCell(location);
                                    if (viewAnswerQuestionVo.getAnswerContent() != null) {
                                        cell.setCellValue(viewAnswerQuestionVo.getAnswerContent());
                                    }
                                }
                                viewAnswerQuestionOptionVos = viewAnswerQuestionVo.getOptions();
                                if (viewAnswerQuestionOptionVos == null) {
                                    continue;
                                }
                                for (int k = 0; k < viewAnswerQuestionOptionVos.size(); k++) {
                                    viewAnswerQuestionOptionVo = viewAnswerQuestionOptionVos.get(k);
                                    if (viewAnswerQuestionVo.getType() == 1 && viewAnswerQuestionOptionVo.getAnswerChecked()) {
                                        cell = row.createCell((short) location);
                                        if (viewAnswerQuestionOptionVo.getContent() != null) {
                                            cell.setCellValue(viewAnswerQuestionOptionVo.getContent());
                                        }
                                        num = viewAnswerQuestionOptionVo.getJumpNum();
                                    } else if (viewAnswerQuestionVo.getType() == 2 && viewAnswerQuestionOptionVo.getAnswerChecked()) {
                                        if (row.getCell(location) != null) {
                                            cell = row.getCell(location);
                                            if (viewAnswerQuestionOptionVo.getContent() != null) {
                                                cell.setCellValue(cell.getStringCellValue() + "$$" + viewAnswerQuestionOptionVo.getContent());

                                            }
                                        } else {
                                            cell = row.createCell(location);
                                            if (viewAnswerQuestionOptionVo.getContent() != null) {
                                                cell.setCellValue(viewAnswerQuestionOptionVo.getContent());
                                            }
                                        }
                                    } else {
                                        optionId = viewAnswerQuestionOptionVo.getId();
                                        if (optionLocationMap.get(optionId) != null) {
                                            location = optionLocationMap.get(optionId);
                                        } else {
                                            continue;
                                        }
                                        cell = row.createCell(location);
                                        if (viewAnswerQuestionOptionVo.getAnswerScore() != null) {
                                            cell.setCellValue(viewAnswerQuestionOptionVo.getAnswerScore());
                                        }
                                    }

                                }
                            }
                        }

                    }

                }
                int location1 = cellSize + 1;
                if (statisticsResearch.getOrgName() != null) {
                    cell = row.createCell((short) location1);
                    cell.setCellValue(statisticsResearch.getOrgName());
                } else {
                    row.createCell((short) location1);
                }
                s++;
//                taskDetail(taskContext.getTaskId(), research.getName() + "导出数据第" + s + "行成功");

            }
            //导出
            StringBuffer fileNameSb = new StringBuffer().append(researchName + "明细统计_" + dateFormat.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);
                //file = new File("E\\");
                success(taskContext, "成功", upLoadUrl);
            } catch (Exception e1) {
                e1.printStackTrace();
                fail(taskContext, "写入过程中发生错误");
                logger.error("写入数据到Excel的过程中或者上传到阿里云中发生错误");
            } finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (workbook != null) {
                    try {
                        workbook.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (file != null) {
                    file.delete();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            fail(taskContext, research.getName() + "导出过程中发生错误，请查看日志");
            logger.error("创建Excel的过程中发生错误");
        }

        return upLoadUrl;
    }
}
