package com.yizhi.application.research.controller.manage;

import cn.hutool.json.JSONUtil;
import com.yizhi.core.application.enums.InternationalEnums;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.research.application.eum.QuestionType;
import com.yizhi.research.application.feign.ResearchQuestionClient;
import com.yizhi.research.application.feign.ResearchQuestionOptionClient;
import com.yizhi.research.application.model.ModifyQuestionModel;
import com.yizhi.research.application.vo.api.QuestionJumpVo;
import com.yizhi.research.application.vo.domain.TrResearchQuestionOptionVo;
import com.yizhi.research.application.vo.domain.TrResearchQuestionVo;
import com.yizhi.research.application.vo.manage.OtherOptionVo;
import com.yizhi.research.application.vo.manage.QuestionEditVo;
import com.yizhi.research.application.vo.manage.QuestionOptionVo;
import com.yizhi.research.application.vo.manage.QuestionVo;
import com.yizhi.statistics.application.refactor.TrResearchQuestionVO;
import com.yizhi.util.application.constant.ReturnCode;
import com.yizhi.util.application.domain.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

//import com.yizhi.application.research.importer.QuestionImporterCallBack;


/**
 * @Author: shengchenglong
 * @Date: 2018/3/14 09:25
 */
@Api(tags = "调研问题接口")
@RestController
@RequestMapping("/manage/researchQuestion")
public class ResearchQuestionController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ResearchQuestionController.class);

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

    @PostMapping("/insert")
    @ApiOperation(value = "新增调研问题", notes = "新增调研问题")
    public Response<Integer> insert(
            @ApiParam(name = "questionVo", value = "问题vo", required = true) @RequestBody QuestionVo questionVo
    ) {
        try {
            if (!checkTye(questionVo.getType())) {
                return Response.fail("4001", InternationalEnums.RESEARCHQUESTIONCONTROLLER1.getCode());
            }
            Date date = new Date();
            RequestContext context = ContextHolder.get();

            List<TrResearchQuestionVo> researchQuestions = new ArrayList<>();
            researchQuestions.add(buildQuestion(context, date, questionVo.getReseachId(), questionVo));
            int num = researchQuestionClient.batchInsert(researchQuestions);
            return Response.ok(num);
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @PostMapping("/batch/insert")
    @ApiOperation(value = "批量新增调研问题", notes = "新增调研问题")
    public Response<Integer> batchInsert(
            @ApiParam(name = "questionVo", value = "问题vo", required = true) @RequestBody List<QuestionVo> questionVos
    ) {

        try {
            if (CollectionUtils.isEmpty(questionVos)) {
                return Response.fail("4001", InternationalEnums.RESEARCHQUESTIONCONTROLLER1.getCode());
            }
            RequestContext context = ContextHolder.get();
            List<TrResearchQuestionVo> researchQuestions = new ArrayList<>();

            // 如果问题集合不为空
            if (!CollectionUtils.isEmpty(questionVos)) {
                Date date = new Date();
                for (QuestionVo questionVo : questionVos) {
                    if (!checkTye(questionVo.getType())) {
                        return Response.fail("4001", InternationalEnums.RESEARCHQUESTIONCONTROLLER1.getCode());
                    }
                    researchQuestions.add(buildQuestion(context, date, questionVo.getReseachId(), questionVo));
                }
            }
            LOGGER.info("web-manage batchInsert 入参:{}", JSONUtil.toJsonStr(researchQuestions));
            int num = researchQuestionClient.batchInsert(researchQuestions);
            return Response.ok(num);
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @PostMapping("/batch/updateNo")
    @ApiOperation(value = "编辑调研问题时，修改问题得排序")
    public Response<Integer> updateNo(@RequestBody QuestionJumpVo vo){
        return Response.ok(researchQuestionClient.updateNo(vo));
    }

    @PostMapping("/batch/update")
    @ApiOperation(value = "编辑调研问题时，修改问题")
    public Response<Integer> update(
            @ApiParam(name = "questionEditVo", value = "问题修改vo", required = true) @RequestBody QuestionEditVo questionEditVo
    ) {
        try {
            Date date = new Date();
            RequestContext context = ContextHolder.get();
            ModifyQuestionModel model = new ModifyQuestionModel();
            model.setDeletedIds(questionEditVo.getDeleteIds());
            model.setDate(date);
            model.setRequestContext(context);
            model.setResearchId(questionEditVo.getResearchId());

            List<QuestionVo> questionVos = questionEditVo.getQuestions();

            if (!CollectionUtils.isEmpty(questionVos)) {
                // 将要入库的问题集合
                List<TrResearchQuestionVo> questionList = new ArrayList<>();
                for (QuestionVo vo : questionVos) {
                    if (!checkTye(vo.getType())) {
                        return Response.fail("4001", InternationalEnums.RESEARCHQUESTIONCONTROLLER1.getCode());
                    }
                    TrResearchQuestionVo trResearchQuestion = buildQuestion(context, date, questionEditVo.getResearchId(), vo);
                    questionList.add(trResearchQuestion);
                }
                model.setQuestions(questionList);
            }
            return Response.ok(researchQuestionClient.batchUpdate(model));
        } catch (Exception e) {
            LOGGER.error("{}", e.getStackTrace());
            LOGGER.info(e.toString());
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    /**
     * 查询调研问题
     *
     * @param researchId
     * @return
     */
    @GetMapping("/page/list")
    @ApiOperation(value = "分页查询调研问题", response = TrResearchQuestionVo.class)
    public Response<List<TrResearchQuestionVo>> listPage(
            @ApiParam(name = "researchId", value = "调研id", required = true) @RequestParam(name = "researchId") Long researchId
    ) {
        try {
            return Response.ok(researchQuestionClient.listAll(researchId));

//            return Response.ok(researchQuestionClient.listAll(researchId));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    /**
     * 选择跳题时的问题列表
     *
     * @param id 需要跳题的问题id
     * @return
     */
    @GetMapping("/jump/question/list")
    @ApiOperation(value = "选择跳题时的问题列表", response = TrResearchQuestionVo.class)
    public Response<List<TrResearchQuestionVo>> listAllForJump(@RequestParam("id") Long id) {
        try {
            return Response.ok(researchQuestionClient.listAllForJump(id));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @PostMapping("/jump/question/update")
    @ApiOperation(value = "新增或者修改跳题规则")
    public Response<Integer>  updateQuestionJump(@RequestBody QuestionJumpVo vo){
        try {
            vo.setContext(ContextHolder.get());
            return Response.ok(researchQuestionClient.updateQuestionJump(vo));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @GetMapping("/option/get")
    @ApiOperation(value = "根据问题id，返回选项列表")
    public Response<Map<String,Object>> getOptionByQuestionId(@RequestParam("questionId") Long id){
        try {
            return Response.ok(researchQuestionClient.getOptionByQuestionId(id));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }


//    @GetMapping("/import")
//    @ApiOperation(value = "问题导入", notes = "调研问题导入")
//    public Response<Integer> importQuestion(
//            @ApiParam(name = "researchId", value = "调研id", required = true) @RequestParam(name = "researchId") Long researchId,
//            @ApiParam(name = "maxNo", value = "当前最大题号", required = true) @RequestParam(name = "researchId") Integer maxNo,
//            @ApiParam(name = "url", value = "ossUrl", required = true) @RequestParam(name = "url") String url
//    ) {
//        try {
//            RequestContext context = ContextHolder.get();
//            Date date = new Date();
//
//            QuestionImporterCallBack callBack = new QuestionImporterCallBack();
//            QuestionImporter importer = new QuestionImporter(url, "", "/tmp", callBack, new Template(), TrResearchQuestion.class);
//            importer.handle();
//            List<TrResearchQuestion> questions = callBack.getQuestions();
//
//            for (TrResearchQuestion question : questions) {
//                maxNo++;
//                question.setResearchId(researchId);
//                question.setDeleted(0);
//                question.setNo(maxNo);
//
//                question.setCreateById(context.getAccountId());
//                question.setCreateTime(date);
//                question.setCreateByName(context.getAccountName());
//
//                question.setOrgId(context.getOrgId() == null ? new Long(0) : context.getOrgId());
//                question.setCompanyId(context.getCompanyId());
//                question.setSiteId(context.getSiteId());
//
//                List<TrResearchQuestionOption> optionList = question.getOptions();
//                if (!CollectionUtils.isEmpty(optionList)) {
//                    for (int i = 0; i < optionList.size(); i++) {
//                        TrResearchQuestionOption option = optionList.get(i);
//                        option.setResearchId(researchId);
//                        option.setDeleted(0);
//                        option.setNo(i + 1);
//                        option.setQuestionType(question.getType());
//                        option.setCreateById(context.getAccountId());
//                        option.setCreateByName(context.getAccountName());
//                        option.setCreateTime(date);
//                    }
//                }
//            }
//            return Response.ok(researchQuestionClient.batchInsert(questions));
//        } catch (Exception e) {
//            LOGGER.error("", e);
//            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
//        }
//    }

    /**
     * 检查type合规
     *
     * @param type
     * @return
     */
    private boolean checkTye(Integer type) {
        return type != null &&
                (type.equals(QuestionType.SINGLE_OPTION_QUESTION.getValue())
                || type.equals(QuestionType.MULTIPLE_OPTION_QUESTION.getValue())
                || type.equals(QuestionType.ASK_ANSWER_QUESTION.getValue())
                || type.equals(QuestionType.POINT_QUESTION.getValue()));
    }

    /**
     * 组装问题
     *
     * @param context
     * @param date
     * @param researchId
     * @param questionVo
     * @return
     */
    private TrResearchQuestionVo buildQuestion(RequestContext context, Date date, Long researchId, QuestionVo questionVo) {
        TrResearchQuestionVo question = new TrResearchQuestionVo();

        // 如果是新增的
        if (null == questionVo.getId()) {
            question.setType(questionVo.getType());
            // 审计字段
            question.setCreateTime(date);
            question.setCreateById(context.getAccountId() == null ? new Long(0) : context.getAccountId());
            question.setCreateByName(context.getAccountName() == null ? "0" : context.getAccountName());

            // 权限字段
            question.setCompanyId(context.getCompanyId());
            question.setSiteId(context.getSiteId());
            question.setOrgId(context.getOrgId() == null ? new Long(0) : context.getOrgId());
        }
        // 如果是修改的
        else if (null != questionVo.getId()) {
            question.setId(questionVo.getId());
            question.setUpdateById(context.getAccountId());
            question.setUpdateByName(context.getAccountName());
            question.setUpdateTime(date);

            LOGGER.info("进入修改阶段----------------------------"+"No:"+questionVo.getNo()+"type"+questionVo.getType());
            if (null != questionVo.getNo() && null != questionVo.getType()) {
                //查出该问题的所有选项VO
                List<TrResearchQuestionOptionVo> options = researchQuestionOptionClient.listOption(questionVo.getId());
                List<QuestionOptionVo> questionOptionVos = new ArrayList<>();
//                LOGGER.info("根据问题Id查询选项内容"+options.toString());
                if (!CollectionUtils.isEmpty(options)) {
                    options.forEach(a -> {
                        QuestionOptionVo optionVo = new QuestionOptionVo();
                        BeanUtils.copyProperties(a, optionVo);
                        questionOptionVos.add(optionVo);
                        LOGGER.info("========================测试=====" + optionVo.toString());
                    });
                    questionVo.setQuestionOptions(questionOptionVos);
                }
            }
        }

        // 如果是单选题
        if (questionVo.getType() == QuestionType.SINGLE_OPTION_QUESTION.getValue()) {
            question.setOptions(buildOptions(questionVo, question, date, context));
        }
        // 如果是多选题
        if (questionVo.getType() == QuestionType.MULTIPLE_OPTION_QUESTION.getValue()) {
            question.setMaxSelectItem(questionVo.getMaxSelectItem());
            question.setMinSelectItem(questionVo.getMinSelectItem());
            question.setOptions(buildOptions(questionVo, question, date, context));
        }
        // 如果是打分题
        if (questionVo.getType() == QuestionType.POINT_QUESTION.getValue()) {
            question.setMaxScore(questionVo.getMaxScore());
            question.setMinScore(questionVo.getMinScore());
            question.setOptions(buildOptions(questionVo, question, date, context));
        }

        question.setResearchId(researchId);
        question.setType(questionVo.getType());
        question.setJumpNum(questionVo.getJumpNum());
        question.setJumpType(question.getType());
        question.setNo(questionVo.getNo());
        question.setContent(questionVo.getContent());
        question.setContentAppendixUrl(questionVo.getContentAppendixUrl());
        question.setNeedAnswer(questionVo.getNeedAnswer());
        question.setDeleted(0);
        question.setKeywords(questionVo.getKeywords());
        question.setAttachmentUrl(questionVo.getAttachmentUrl());
        question.setLogoSrc(questionVo.getLogoSrc());

        return question;
    }

    /**
     * 组装单选题、多选题、打分题的option
     *
     * @param questionVo
     * @return
     */
    private List<TrResearchQuestionOptionVo> buildOptions(QuestionVo questionVo, TrResearchQuestionVo question, Date date, RequestContext requestContext) {
        addOtherToOption(questionVo);
        int type = questionVo.getType();
        List<TrResearchQuestionOptionVo> optionList = new ArrayList<>();
        // 获取
        List<QuestionOptionVo> optionVos = questionVo.getQuestionOptions();
        for (QuestionOptionVo optionVo : optionVos) {
            TrResearchQuestionOptionVo option = new TrResearchQuestionOptionVo();
            // 如果是新增
            if (null == optionVo.getId()) {
                // 审计字段
                option.setCreateTime(date);
                option.setCreateById(requestContext.getAccountId() == null ? new Long(0) : requestContext.getAccountId());
                option.setCreateByName(requestContext.getAccountName() == null ? "0" : requestContext.getAccountName());
                option.setQuestionType(questionVo.getType());
                option.setRequired(optionVo.getRequired());
                option.setIsOther(optionVo.getIsOther());
                // 如果是单选题
                if (type == QuestionType.SINGLE_OPTION_QUESTION.getValue()) {
                    /*if (null != optionVo.getJumpNum()) {
                        question.setJumpable(Jumpleable.YES.getValue());
                        option.setJumpNum(optionVo.getJumpNum());
                    } else {
                        question.setJumpable(Jumpleable.NO.getValue());
                    }*/
                    option.setJumpNum(optionVo.getJumpNum());
                }
                // 如果是单选题 或者 多选题
                if (type == QuestionType.SINGLE_OPTION_QUESTION.getValue() || type == QuestionType.MULTIPLE_OPTION_QUESTION.getValue()) {
                    option.setEditable(optionVo.getEditable());
                    option.setCorrect(optionVo.getCorrect());
                }
                // 如果是 打分题
                if (type == QuestionType.POINT_QUESTION.getValue()) {
                    option.setMaxScore(optionVo.getMaxScore());
                    option.setMinScore(optionVo.getMinScore());
                }
            }

            // 如果是修改
            if (null != optionVo.getId()) {
                option.setId(optionVo.getId());
                option.setUpdateById(requestContext.getAccountId());
                option.setUpdateTime(date);
                option.setUpdateByName(requestContext.getAccountName());
            }

            option.setContent(optionVo.getContent());
            option.setDeleted(0);
            option.setNo(optionVo.getNo());

            optionList.add(option);
        }
        return optionList;
    }

    /**
     * 将其他选项添加进选项
     * @param questionVo
     * @return
     */
    public void addOtherToOption(QuestionVo questionVo){
        if(questionVo == null || questionVo.getHasOther() == null || questionVo.getHasOther() == 0){
            return;
        }
        List<QuestionOptionVo> questionOptions = questionVo.getQuestionOptions();
        QuestionOptionVo trResearchQuestionOption = new QuestionOptionVo();
        OtherOptionVo otherOption = questionVo.getOtherOption();
        if(questionOptions !=null && otherOption !=null){
            trResearchQuestionOption.setId(otherOption.getId());
            trResearchQuestionOption.setNo(otherOption.getNo());
            trResearchQuestionOption.setEditable(otherOption.getEditable());
            trResearchQuestionOption.setJumpNum(otherOption.getJumpNum());
            //trResearchQuestionOption.setNo(-1);
            trResearchQuestionOption.setContent(otherOption.getContent());
            trResearchQuestionOption.setRequired(otherOption.getRequired());
            trResearchQuestionOption.setIsOther(1);
            questionOptions.add(trResearchQuestionOption);
        }
        questionVo.setQuestionOptions(questionOptions);
    }

    @GetMapping("/delete")
    @ApiOperation(value = "删除投票中问题")
    public Response<Map<String,Object>> deleteByResearchIdAndQueId(@RequestParam("questionId") Long questionId, @RequestParam("researchId") Long researchId){
        try {
            return Response.ok(researchQuestionClient.deleteByResearchIdAndQueId(questionId, researchId));
        } catch (Exception e) {
            LOGGER.error("", e);
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }
}
