package com.yizhi.application.exam.controller;


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.exam.application.feign.QuestionLibraryClient;
import com.yizhi.exam.application.feign.QuestionLibraryOptionClient;
import com.yizhi.exam.application.feign.QuestionLibrarySubjectClient;
import com.yizhi.exam.application.vo.domain.TrQuestionLibrarySubject;
import com.yizhi.exam.application.vo.domain.TrQuestionSubjectOption;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <功能>导出题库试题</>
 */

@Component
public class LibrarySubjectExport extends AbstractDefaultTask<String, Map<String, Object>> {
    private String upload = null;
    private String TASKNAME = "题库试题excel导出任务";
    private int titleRowIndex = 0; //标题行索引

    private String sheetName = "题库试题导出";
    private Integer pageSize = 20;
    private Integer pageNo = 1;
    private static Logger LOGGER = LoggerFactory.getLogger(LibrarySubjectExport.class);
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-hh HH:mm:ss");


    @Autowired
    QuestionLibraryClient questionLibraryClient;
    @Autowired
    QuestionLibrarySubjectClient questionLibrarySubjectClient;
    @Autowired
    QuestionLibraryOptionClient questionLibraryOptionClient;

    @Override
    protected String execute(Map<String, Object> map) {
        Long companyId = Long.valueOf(map.get("companyId").toString());
        Long accountId = Long.valueOf(map.get("accountId").toString());
        Long siteId = Long.valueOf(map.get("siteId").toString());
        Long orgId = Long.valueOf(map.get("orgId").toString());
        Long libraryId = Long.valueOf(map.get("libraryId").toString());
        Date date = new Date();
        Long taskId = Long.valueOf(map.get("taskId").toString());
        String taskName = new StringBuffer().append(TASKNAME).append("-").append(taskId).toString();
        String libraryName = questionLibraryClient.selectQuestionLibraryById(libraryId).getName();
        sheetName = libraryName;

        //创建任务
        TaskContext taskContext = new TaskContext(taskId, taskName, accountId, date, siteId, companyId);//任务id、任务名称、操作人ID、操作时间
        working(taskContext);

        try {

            HSSFWorkbook workBook = null;//工作簿对象
            HSSFSheet sheet = null;      //表单对象
            HSSFRow row = null;          //行对象
            HSSFRow titleRow = null;     //标题行对象
            HSSFCell cell = null;        //单元格对象
            workBook = new HSSFWorkbook();
            StringBuffer fileName = null;

            //给excel表取个名称
            if (!StringUtils.isBlank(sheetName)) {
                fileName = new StringBuffer().append(sheetName).append("--").append(taskId).append(".xls");
                sheet = workBook.createSheet(fileName.toString());
            }
            //设置标题行  题型 题干 标签 题目解析 正确答案  因为选项个数不固定 所以在下面代码中动态生成
            //第一行
            titleRow = sheet.createRow(titleRowIndex);
            String title[] = new String[]{"题型", "题干", "标签", "题目解析", "正确答案"};
            for (int i = 0; i < title.length; i++) {
                cell = titleRow.createCell(i);
                cell.setCellValue(title[i]);
            }

            //分页获取数据    分为两部分   一部分是查出试题（subject）表数据，一部分查选项（option）表数据

            List<TrQuestionLibrarySubject> trQuestionLibrarySubjects = null;
            List<TrQuestionLibrarySubject> resultList = new ArrayList<>();
            List<TrQuestionSubjectOption> trQuestionSubjectOptions = null;
            TrQuestionSubjectOption trQuestionSubjectOption;
            TrQuestionLibrarySubject trQuestionLibrarySubject;

            try {
                //获取所需要的题库中分页中所有subject试题
                pageNo = (Integer) map.get("pageNo");
                pageSize = (Integer) map.get("pageSize");
                Integer subjectNum = (Integer) map.get("subjectNum");
                if (subjectNum == null) {
                    subjectNum = 0;
                }
                if (pageNo > 0 && pageSize > 0) {
                    Integer pageTotal = subjectNum / pageSize;
                    if (pageTotal == 0) {
                        trQuestionLibrarySubjects = questionLibrarySubjectClient.queryQuestionLibraryList(libraryId, pageNo, pageSize);
                        if (!CollectionUtils.isEmpty(trQuestionLibrarySubjects)) {
                            resultList.addAll(trQuestionLibrarySubjects);
                        }
                    } else {
                        for (int i = 1; i <= pageTotal; i++) {
                            trQuestionLibrarySubjects = questionLibrarySubjectClient.queryQuestionLibraryList(libraryId, i, pageSize);
                            if (!CollectionUtils.isEmpty(trQuestionLibrarySubjects)) {
                                resultList.addAll(trQuestionLibrarySubjects);
                            }
                        }
                        if (subjectNum % pageSize > 0) {
                            trQuestionLibrarySubjects = questionLibrarySubjectClient.queryQuestionLibraryList(libraryId, pageTotal + 1, pageSize);
                            if (!CollectionUtils.isEmpty(trQuestionLibrarySubjects)) {
                                resultList.addAll(trQuestionLibrarySubjects);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                LOGGER.error("查询对应的subject表数据出错", e);
                fail(taskContext, "查询对应的subject表数据出错");
            }

            int dateRowIndex = 1;//数据行索引
            if (resultList.size() > 0 && null != resultList) {
                for (int i = 0; i < resultList.size(); i++) {
                    Integer type = 0;              //题型
                    String stem = null;            //题干
                    String questionLabel = null;   //标签
                    String analysis = null;        //题目解析
                    Integer isAnswer = 0;          //正确答案
                    Integer sort = 0;              //排序
                    String content = null;         //选项
                    String score_rule = null;

                    //获取单个subject试题
                    trQuestionLibrarySubject = resultList.get(i);
                    if (null != trQuestionLibrarySubject) {
                        type = trQuestionLibrarySubject.getType();
                        stem = trQuestionLibrarySubject.getStem();
                        questionLabel = trQuestionLibrarySubject.getQuestionLabel();
                        analysis = trQuestionLibrarySubject.getAnalysis();
                        score_rule = trQuestionLibrarySubject.getScoreRule();
                    }
                    //开始填充数据
                    //题型 题干 标签 题目解析 正确答案 因为选项个数不固定 所以在下面代码中动态生成
                    //第二行

                    row = sheet.createRow(dateRowIndex++);
                    cell = row.createCell(0);


                    try {
                        switch (type) {
                            case 1:
                                cell.setCellValue("单选题");
                                break;
                            case 2:
                                cell.setCellValue("多选题");
                                break;
                            case 3:
                                cell.setCellValue("判断题");
                                break;
                            case 4:
                                cell.setCellValue("问答题");
                                break;
                            default:
                                fail(taskContext, "type值超出范围");
                                break;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        LOGGER.error("type为空，数据库数据有问题");
                        fail(taskContext, "type为空，数据库数据有问题");
                    }
                    cell = row.createCell(1);
                    //题干赋值
                    cell.setCellValue(stem);
                    cell = row.createCell(2);
                    //标签赋值
                    cell.setCellValue(questionLabel);
                    cell = row.createCell(3);
                    //题目解析赋值
                    cell.setCellValue(analysis);

                    if (type == 4) {

                        //问答题的正确答案是在score_rule字段里
                        cell = row.createCell(4);
                        cell.setCellValue(score_rule);
                    }

                    //因为type为4代表的是问答题，  是没有选项的 ，需要过滤问答题
                    else if (type == 1 || type == 2 || type == 3) {
                        Long subjectId = trQuestionLibrarySubject.getId();
                        if (null != subjectId && subjectId != 0) {
                            try {
                                //获取所需的试题的所有选项}
                                trQuestionSubjectOptions = questionLibraryOptionClient.QueryTrQuestionSubjectOptionList(subjectId);
                                LOGGER.info("这是第-------" + i + "------条数据");
                                //LOGGER.info("trQuestionSubjectOptions.size:" + "===========================" + trQuestionSubjectOptions.size());
                            } catch (Exception e) {
                                //e.printStackTrace();
                                LOGGER.error("查询对应的option表数据出错", e);
                                //fail(taskContext, "查询对应的option表数据出错");

                            }
                            if (null != trQuestionSubjectOptions && trQuestionSubjectOptions.size() > 0) {
                                String tem = "";
                                for (int j = 0; j < trQuestionSubjectOptions.size(); j++) {

                                    //获取所需的试题的具体选项数据
                                    trQuestionSubjectOption = trQuestionSubjectOptions.get(j);
                                    content = trQuestionSubjectOption.getContent();
                                    isAnswer = trQuestionSubjectOption.getIsAnswer();
                                    sort = j + 1;


                                    if (isAnswer == 1) {
                                        tem = tem + sort.toString() + ",";

                                    }
                                    //正确答案赋值
                                    cell = row.createCell(4);
                                    cell.setCellValue(tem);

                                    //因为选项个数不固定，所以根据查出选项的Size值 去创建标题行选项
                                    cell = titleRow.createCell((5 + j));
                                    cell.setCellValue("选项" + (1 + j));

                                    //选项赋值
                                    cell = row.createCell((5 + j));
                                    cell.setCellValue(content);
                                }
                                //去除正确答案字符串后的标点符号----“.”
                                String s = null;
                                if (tem.lastIndexOf(",") != -1) {
                                    s = tem.substring(0, tem.lastIndexOf(","));
                                } else {
                                    s = tem;
                                }
                                row.getCell(4).setCellValue(s == null ? "" : s);
                            } else {
                                LOGGER.error("查询出来的OptionList数据为null");
                                fail(taskContext, "查询出来的OptionList数据为null");
                                continue;
                            }
                        } else {
                            LOGGER.error("查询出来的subjectId为null");
                            fail(taskContext, "查询出来的subjectId为null");
                            continue;
                        }
                    } else {
                        LOGGER.error("type值不对");
                        fail(taskContext, "type值不对");
                        continue;
                    }
                    //taskDetail(taskId, "导出数据第+" + i + "+行成功");
                }

            } else {
                LOGGER.error("查询对应的subject表数据List为空");
                fail(taskContext, "查询对应的subject表数据List为空");
            }

            //阿里云返回url
            upload = getFileUrl(fileName.toString(), workBook, upload, taskContext);
            if (null == upload) {
                LOGGER.error("upload 这个URL为空");
                fail(taskContext, "upload 这个URL为空");
            }

        } catch (Exception e) {
            e.printStackTrace();
            fail(taskContext, "导出任务出错");
        }

        return upload;

    }

    public String getFileUrl(String fileName, HSSFWorkbook workBook, String upload, TaskContext taskContext) {
        FileOutputStream os = null;
        File file = null;
        try {

            String path = new StringBuffer().append(FileConstant.SAVE_PATH).toString();
//            String path = "/Users/dingxiaowei/aaa";
            File fileDir = new File(path);
            file = new File(path);
            if (!fileDir.exists()) {
                fileDir.mkdir();
            }
            String pathFile = new StringBuffer().append(path).append("/").append(fileName).toString();
            os = new FileOutputStream(pathFile);
            workBook.write(os);
            upload = OssUpload.upload(pathFile, fileName);
            success(taskContext, upload);
        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.info("写入过程出错");
            fail(taskContext, "写入过程出错");
            return null;
        } 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();
            }

        }
        return upload;
    }
}
